SDL source code reading (questions about preprocessor)

Reading the SDL sources I could find many prototype declarations like this:

extern DECLSPEC float SDLCALL SDL_expf(float x);

What is the difference for

extern float SDL_expf(float x);

That is, what means DECLSPEC and SDLCALL?

DECLSPEC is a macro for the __declspec(dllexport) keyword. That keyword is used to export data, functions, classes etc from a dll file.
The function signature of SDL_expf() is defined in SDL_stdinc.h and the function body will be defined/extracted from the SDL dll file during runtime.
Check this site for more information: https://docs.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-declspec-dllexport?view=vs-2019

SDLCALL is a macro for the __cdecl keyword.
As I understand it, it’s just a calling convention and SDL uses the C calling convention by default. I found this explanation of the keyword:

"When you call a function, what happens at the assembly level is all the passed-in parameters are pushed to the stack, then the program jumps to a different area of code. The new area of code looks at the stack and expects the parameters to be placed there.

Different calling conventions push parameters in different ways. Some might push the first parameter first, or some might push the first param last. Or some might keep a parameter in a register and not push it at all.

By specifying a calling convention, you are telling the compiler how the parameters are to be pushed.

Usually you don’t have to care about this crap, since it doesn’t really matter what convention you use – they all pretty much do the same thing. But when dealing with external libraries — it’s important for the calling convention used in the lib to match the calling convention used in the code that is calling into the lib, or else your parameters will be all messed up when you call a lib function."

So writing
extern DECLSPEC float SDLCALL SDL_expf(float x); is the same as writing
extern DECLSPEC float SDL_expf(float x);

1 Like

Also, __cdecl and __declspec(dllexport) are only relevant on Windows, on other platforms those macros will either be empty (just #define DECLSPEC), or do something else for the given platform for example, instead of __declspec(dllexport) you could use __attribute__((visibility("default"))) with GCC or clang on Linux (and probably some other platforms) to achieve something similar.

1 Like