1

When learning about debugging OpenGL I implemented a function callback which would receive any debug error messages from the OpenGL API whenever something went wrong. In the tutorial it said that the function signature was:

typedef void APIENTRY funcname(GLenum source​, GLenum type​, GLuint id​,
   GLenum severity​, GLsizei length​, const GLchar* message​, const void* userParam​);

So on Windows I implemented this callback. On Windows APIENTRY is a define for __stdcall. __stdcall I believe is a Windows-specific keyword specifying the calling convention. Later I ported my code to Linux, and for starters my GCC with Eclipse didn't recognise APIENTRY, because it's a Windows define. So I changed it to __stdcall, which I'm not sure if it recognised or not, but regardless it threw an error saying:

"Expected initialiser before glCheckError_"

As my callback function is void __stdcall glCheckError_(/Params/). Removing the __stdcall preface makes the program work fine without it.

I'm wondering whether this prefix is necessary, for either Windows or Linux? The funny thing is that the place that suggested I add __stdcall to the function signature was the Khronos webpage, which holds documentation for OpenGL, so as far as I can tell it shouldn't be specifying OS-specific information, as OpenGL is cross-platform. So do I need this __stdcall prefix?

Zebrafish
  • 11,682
  • 3
  • 43
  • 119
  • That keyword is specific to Visual C++ – Asesh Oct 03 '17 at 03:16
  • Both APIENTRY and __stdcall, right? I find it strange that the OpenGL docs mention to make the callback in this way. Because it wasn't a Windows-specific tutorial. – Zebrafish Oct 03 '17 at 03:18
  • 1
    APIENTRY is #defined as __stdcall – Asesh Oct 03 '17 at 03:21
  • @Asesh Yeah, I'm tempted to leave this out and wait to see what happens. It's a callback that's called by the OpenGL API, so I'm guessing it has nothing to do with Windows, ie., Windows isn't calling the callback. Though whether this __stdcall is needed when using the OpenGL on Windows, I don't know. Well I can try and see. – Zebrafish Oct 03 '17 at 03:24
  • __stdcall is a calling convention which defines how parameters are pushed on to the stack. I don't see any APIs on Khronos' website using that calling convention – Asesh Oct 03 '17 at 03:25
  • 1
    @Asesh Here for example, under "The type of the callback function is of form: https://www.khronos.org/opengl/wiki/Debug_Output#Getting_messages – Zebrafish Oct 03 '17 at 03:33
  • If you don't specify a calling convention then the compiler will use default calling convention. In Visual C++, it's generally __cdecl calling convention – Asesh Oct 03 '17 at 03:40

1 Answers1

3

On windows, and only under 32bit, then it will make a difference. (The default is __cdecl calling convention, v.s. the __stdcall used by openGL). This can end up corrupting the stack if you use the wrong convention (the compiler should error with any luck).

On 64bit windows, it makes no difference (because stdcall isn't available, so all __stdcall/__cdecl will default to __fastcall).

It make no difference to linux/macos/android/ios.

Wrapping this in a macro should be all that's needed.

#if definded(_WIN32) && !defined(_WIN64)
# define STDCALL __stdcall
#else 
# define STDCALL 
#endif
robthebloke
  • 9,331
  • 9
  • 12
  • Really? That's very helpful. I did a bit of searching, including reading some answers here on SO about the difference in calling convention, this 32 bit vs 64 bit business was never mentioned. Thanks. – Zebrafish Oct 03 '17 at 04:22
  • Yup. On 64bit windows you have two options for the calling conventions: __fastcall or __vectorcall, where __vectorcall makes use of more registers when passing floating point / vector arguments (rather than falling back to the stack). Linux/BSD/Macos all use __vectorcall only (with a slight difference to which general purpose registers are used - not really an issue) The only other choice you have (available on all platforms) is 'extern "C"' (disable C++ name mangling), or to not extern C (enable C++ name mangling). – robthebloke Oct 03 '17 at 04:37