Weird Function Declaration

S

Steve Chow

I recently saw this in some C++/OpenGL (it is apparently required)
code (and this is a C++ question, not OpenGL). And the relevant part
went something like this:

#ifndef CALLBACK
#define CALLBACK
#endif

void CALLBACK function_name()

my question is: what the hell? what exactly is happening here? I've
never seen type identifier function_name() used in any C++ code
before. Of course, I am an amateur. Where would one use this? Why?
 
J

Juha Nieminen

Steve said:
I recently saw this in some C++/OpenGL (it is apparently required)
code (and this is a C++ question, not OpenGL). And the relevant part
went something like this:

#ifndef CALLBACK
#define CALLBACK
#endif

void CALLBACK function_name()

my question is: what the hell? what exactly is happening here? I've
never seen type identifier function_name() used in any C++ code
before. Of course, I am an amateur. Where would one use this? Why?

What you see above is exactly what you get. The "CALLBACK" does
absolutely nothing and has no effect on anything. What do you expect?

That, however, is a common technique for telling some higher-level
programs (such as GUI design applications) that the function in question
is somehow special. The C++ compiler itself doesn't know about it, and
only sees that it's an empty preprocessor macro, and thus doesn't do
anything with it. But the higher-level app which you might be using may
use that keyword for something, for its own purposes.
 
S

Steve Chow

  What you see above is exactly what you get. The "CALLBACK" does
absolutely nothing and has no effect on anything. What do you expect?

  That, however, is a common technique for telling some higher-level
programs (such as GUI design applications) that the function in question
is somehow special. The C++ compiler itself doesn't know about it, and
only sees that it's an empty preprocessor macro, and thus doesn't do
anything with it. But the higher-level app which you might be using may
use that keyword for something, for its own purposes.

Keep in mind, I'm a noob.

But it appears you're correct only 99% of the time. :) Apparently
CALLBACK does actually mean something in Windows, it's a nice way of
saying __stdcall, which is apparently some proprietary calling
convention hackery which is necessary sometimes.

So I guess it's just there to maintain Windows compatibility, so they
don't have to use separate functions & doesn't mean anything on other
platforms.
 
P

Puppet_Sock

But it appears you're correct only 99% of the time. :) Apparently
CALLBACK does actually mean something in Windows, it's a nice way of
saying __stdcall, which is apparently some proprietary calling
convention hackery which is necessary sometimes.

Not in Windows, but in some library code provided with
some compilers. Your example is not relevant to that
though, since in your example you have CALLBACK defined
to be nothing.

Windows as such does not know from the definition of
CALLBACK in source code. It's an OS. (Sort of.)
Socks
 
J

jason.cipriani

Keep in mind, I'm a noob.

But it appears you're correct only 99% of the time. :) Apparently
CALLBACK does actually mean something in Windows, it's a nice way of
saying __stdcall, which is apparently some proprietary calling
convention hackery which is necessary sometimes.

This is correct. In fact, many compilers support various attributes
that can be placed on functions and are specified in various places.
For example, MSVC has all the __declspec attributes as well as calling
conventions (__stdcall, __cdecl, __fastcall, etc.), GCC has
__attribute__ which is generally placed after the parameter list
(compiler-specific attributes are not limited to Microsoft).

None of it is defined by C++ although C++0x will add attributes to the
language in an attempt to standardize all the compiler-specific
variants.

"CALLBACK" itself doesn't mean anything, it's just a macro. In Windows
it's also #define'd to __stdcall (as is "WINAPI"). The use of
"CALLBACK" there is fairly idiomatic to a Windows developer, but
doesn't make much sense to anybody else.

In code designed to be portable you will frequently see what you saw:
"CALLBACK" used as a placeholder #defined to appropriate values
depending on the platform.

So I guess it's just there to maintain Windows compatibility, so they
don't have to use separate functions & doesn't mean anything on other
platforms.

Yes, although, of course, in a more general sense, it maintains
compatibility with any compiler where some useful attributes in that
position would be required (which includes MSVC).


Jason
 
J

jason.cipriani

Not in Windows, but in some library code provided with
some compilers. Your example is not relevant to that
though, since in your example you have CALLBACK defined
to be nothing.

Windows as such does not know from the definition of
CALLBACK in source code. It's an OS. (Sort of.)

Windows does #define CALLBACK to __stdcall (it's defined in windef.h
[which you generally include via windows.h]). It is only used with
MSVC. It would not be defined to anything on, say, MinGW GCC. From
windef.h:

#ifdef _MAC
# define CALLBACK PASCAL
....
# ifdef _68K_
# define PASCAL __pascal
# else
# define PASCAL
# endif
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
# define CALLBACK __stdcall
....
#else
# define CALLBACK
....
#endif


Jason
 
J

jason.cipriani

CALLBACK is only defined to be nothing if it was not previously defined,
e.g. by an included file or compiler flag.  Defining it could also
control the behavior of subsequently included files.


I think Juha called it:  Some code processor, orthogonal to the
traditional too chain, may look for CALLBACKs.  A very similar mechanism
is used with Apple's Interface Builder in the form of the IBOutlet
macro.  In fact, Objective-C actions (a flavor of callbacks) are
generally marked with the IBAction macro, whose definition is the moral
equivalent of "#define IBAction void".


"CALLBACK" may be used by some code processors, in my experience that
is generally not the case, for a number of reasons:

1) On Windows CALLBACK specifies a calling convention, while using it
to mark a function conceptually as a "CALLBACK" won't generally cause
any harm, it's more for specifying calling conventions rather than
conceptual intentions. So, despite the name "CALLBACK", it's not
really a good choice for identifying callback functions in general.

2) Many Windows programmers tend to get sloppy about it and specify
either __stdcall directory, or use WINAPI, or some other application-
specific macro. The word "CALLBACK" itself may not be a reliable
choice for identifying callback functions. For example, a window
procedure in the Windows API uses "CALLBACK" in the documentation
( http://msdn.microsoft.com/en-us/library/ms633573(VS.85).aspx ), but
it is not unusual to see a programmer doing this instead:

LRESULT WINAPI mywndproc (HWND, UINT, WPARAM, LPARAM);


A code processor designed to do something with callback functions
would probably be better served by requiring you to use some other
macro besides "CALLBACK" to specify such functions, thus making your
declaration of a function as a callback function independent of your
use of standard Windows macros.

I can tell you that, AFAIK, the Visual Studio IDE itself does not use
the presence of "CALLBACK" for any code processing tasks.


Jason
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,440
Latest member
YoungBorel

Latest Threads

Top