0

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);
}
Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
lodkkx
  • 1,163
  • 2
  • 17
  • 29

3 Answers3

9

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.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • One could cast the port number to "void *", thus passing it by value. You can say that "void *" is the "generic type" you talk about (though int64 may be larger). But I admit it just makes things uglier. – ugoren Jan 02 '12 at 10:16
  • @ugoren: it could work for integral types (although, I'm not sure that it would yield well-defined behavior), but surely almost any struct wouldn't be small enough (and it would require a strange sequence of casts). – Matteo Italia Jan 02 '12 at 13:02
2

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.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
1

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.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680