5

I'm designing a C API which will have about a dozen getter functions for various values. Something like:

bool getSomeBool();
bool getSomeOtherBool();
...
int getSomeNumber();
int getSomeOtherNumber();
...

This seems to me like a straightforward way to do it, easy to implement, easy to document, hard to use incorrectly.

However, in APIs like OpenGL, we encounter something like the following (simplified):

typedef unsigned int GLenum;

bool glGetBool(GLenum pname);
int glGetInteger(GLenum pname);

#define GL_BLEND           0x0BE2  /* may be passed to glGetBool    */
#define GL_ACTIVE_TEXTURE  0x84E0  /* may be passed to glGetInteger */

This has the obvious drawbacks that the enum value must match the function that it's being passed to, and that the enum value must be a valid enum value to begin with.

So surely, this approach must have some advantage too?

Extensibility comes to mind – we can now add new enum values without having to add new functions – but I don't see how that's any better than adding functions.

4

Extensibility comes to mind – we can now add new enum values without having to add new functions – but I don't see how that's any better than adding functions.

Actually, it does promote extensibility.

Adding functions requires the client of the API to always match the version of the API at compile time. With the enum, a well-written client can take decide at run time whether it can take advantage of the features of newer implementations of the API.

This requires a convention in the API, like having an API that lets the client query for available features, or by requiring the API to do nothing but return a well-known value for any option it doesn't support.

This is useful if the API is going to be implemented in a shared library or DLL provided by the system. That said, it puts a bit of a burden on the client to not screw things up.

  • Yes! That must be it. The dynamic linker might fail to resolve symbols if we use functions and run with an older library version that doesn't have those functions, even if we would never call them. Because my clients are going to be bundling my library, this will not be an issue for me. Thank you! – Thomas Jan 29 at 7:30
1

[I'll offer a guess.]

At its compile time, the code which consumes the API (client code) doesn't know which parameter it will want to get from the API. Perhaps, the parameters is specified at run time. One way in which the designers of the API can enable such run time flexibility is by creating a "property dictionary", which the client code can look at run time.

Of course, this isn't the only method for achieving such flexibility. Two more come to mind: function pointers to getters, reflection (although C doesn't support reflection).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.