Question

I am writing some code for a linux program I am working on that requires libssh. I was looking at their tutorial page and I saw that it passes all the parameters to ssh_options_set() by reference. Why is that?

#include <libssh/libssh.h> 
#include <stdlib.h>

int main()
{
  ssh_session my_ssh_session;
  int verbosity = SSH_LOG_PROTOCOL;
  int port = 22;

  my_ssh_session = ssh_new();
  if (my_ssh_session == NULL)
    exit(-1);

  ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
  ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); //here
  ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port); //here

  ...

  ssh_free(my_ssh_session);
}
Was it helpful?

Solution

It's a trick to bypass the type system.

Since the various options that can be set are of various types, the function accepts a const void * as last argument (i.e. the option value, see the documentation) to be able to receive a pointer to any type; such pointer will be re-casted to the correct pointer type inside ssh_options_set, depending on the particular option that is being set.

This couldn't be done with pass by value, because there's no "generic type" you can cast any other type to (even just for the fact that various types have various sizes - a pointer, instead, on a given architecture is always of the same size, whatever type it refers to); to solve or mitigate this problem in C++ there are overloads and templates, but here we are talking about C.

OTHER TIPS

It's because ssh_options_set expects a pointer as the third argument. It works out the actual data type based on the value of the second argument.

Presumably because the actual data type required depends on which option you're setting. Passing everything by address via a const void * is an easy way of achieving that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top