The usual form of function pointer definitions is:
int function(int, int);
int (*ptr)(int, int);
but I saw a form today which I didn't understand. Can anyone explain this please?
int (*close) __P((struct __db *));
The __P() macro is usually used to support C implementations from the days of K&R C, when there were no prototypes (which were introduced to C with C89). Basically the logic is
#if SOME_LOGIC_TO_TEST_WHETHER_IMPLEMENTATION_SUPPORTS_PROTOTYPES
# define __P(argument_list) argument_list
#else
# define __P(argument_list) ()
#endif
Can you see how this works when applied to your example? Note that for this to work and not cause a syntax error, the argument list must include the parentheses of the function call, not just the parentheses of the function-like macro. Hence the double parentheses when the macro is used. That's probably the reason why it looks unusual.
__P() is just a macro. On my system it is defined as follows (in sys/cdefs.h):
#if defined(__STDC__) || defined(__cplusplus)
#define __P(protos) protos /* full-blown ANSI C */
#else /* !(__STDC__ || __cplusplus) */
#define __P(protos) () /* traditional C preprocessor */
#endif /* !__GNUC__ */
From this, it seems to be used to maintain compatibility with (very) old compilers.
The usual form of function pointer definitions is .... but I saw a
form today which I didn't understand.
There is nothing special here, no magic syntax. This is not a different form of function pointer declaration.
This is just the standard form of function pointer declaration, and __P() is a macro defined by one of the header files that you are using. So, find that macro definition to learn what its purpose is.
Related
The usual form of function pointer definitions is:
int function(int, int);
int (*ptr)(int, int);
but I saw a form today which I didn't understand. Can anyone explain this please?
int (*close) __P((struct __db *));
The __P() macro is usually used to support C implementations from the days of K&R C, when there were no prototypes (which were introduced to C with C89). Basically the logic is
#if SOME_LOGIC_TO_TEST_WHETHER_IMPLEMENTATION_SUPPORTS_PROTOTYPES
# define __P(argument_list) argument_list
#else
# define __P(argument_list) ()
#endif
Can you see how this works when applied to your example? Note that for this to work and not cause a syntax error, the argument list must include the parentheses of the function call, not just the parentheses of the function-like macro. Hence the double parentheses when the macro is used. That's probably the reason why it looks unusual.
__P() is just a macro. On my system it is defined as follows (in sys/cdefs.h):
#if defined(__STDC__) || defined(__cplusplus)
#define __P(protos) protos /* full-blown ANSI C */
#else /* !(__STDC__ || __cplusplus) */
#define __P(protos) () /* traditional C preprocessor */
#endif /* !__GNUC__ */
From this, it seems to be used to maintain compatibility with (very) old compilers.
The usual form of function pointer definitions is .... but I saw a
form today which I didn't understand.
There is nothing special here, no magic syntax. This is not a different form of function pointer declaration.
This is just the standard form of function pointer declaration, and __P() is a macro defined by one of the header files that you are using. So, find that macro definition to learn what its purpose is.
In one of my project source files, I found this C function definition:
int (foo) (int *bar)
{
return foo (bar);
}
Note: there is no asterisk next to foo, so it's not a function pointer. Or is it?
What is going on here with the recursive call?
In the absence of any preprocessor stuff going on, foo's signature is equivalent to
int foo (int *bar)
The only context in which I've seen people putting seemingly unnecessary parentheses around function names is when there are both a function and a function-like macro with the same name, and the programmer wants to prevent macro expansion.
This practice may seem a little odd at first, but the C library sets a precedent by providing some macros and functions with identical names.
One such function/macro pair is isdigit(). The library might define it as follows:
/* the macro */
#define isdigit(c) ...
/* the function */
int (isdigit)(int c) /* avoid the macro through the use of parentheses */
{
return isdigit(c); /* use the macro */
}
Your function looks almost identical to the above, so I suspect this is what's going on in your code too.
The parantheses don't change the declaration - it's still just defining an ordinary function called foo.
The reason that they have been used is almost certainly because there is a function-like macro called foo defined:
#define foo(x) ...
Using (foo) in the function declaration prevents this macro from being expanded here. So what is likely happening is that a function foo() is being defined with its body being expanded from the function-like macro foo.
The parentheses are meaningless.
The code you show is nothing but an infinite recursion.
When defining a function pointer, you sometimes see strange parentheses that do mean something. But this isn't the case here.
I was reading opengl es book and in the source code i found this Macro
///
// Macros
//
#define ESUTIL_API
#define ESCALLBACK
later in the implementation file .c
void ESUTIL_API esInitContext ( ESContext *esContext )
{
if ( esContext != NULL )
{
memset( esContext, 0, sizeof( ESContext) );
}
}
from what I understand macros, they just replace what is defined by the macro.. although i don't understand what it is the point in this case.
Thanks.
This kind of macro is used to change the calling convention that is used by the compiler:
#define ESUTIL_API // nothing, use the standard calling convention
or
#define ESUTIL_API __fastcall // use the fastcall calling convention
The call type calling convention has usually to be put in a function definition between the return type and the function identifier name.
In this case is just a placeholder, in case one would ever need to add any decorations to the function declaration, more specifically, stuff like __declspec(dllexport), calling conventions or inlining requirements.
In this case ESUTIL_API macro can be replaced by the calling convention specification.
There may be some other place (or condition) where that macro is defined differently - for example a -D option to a compiler, or another block of code that is triggered by some other #defines. In that case you have to define at least an empty macro so that you can safely use it in a declaration like that and if the macro happens to be re-defined to a non-empty value - it will be used as such.
In some Bison code, what does the following line mean?
#define YY_DECL extern "C" int yylex();
I know #define command but I don't understand the whole command.
It means that YY_DECL will be expanded to
extern "C" int yylex();
This is actually C++, not C; when you compile this file with a C++ compiler, it declares that the function yylex must be compiled with "C linkage", so that C functions can call it without trouble.
If you don't program in C++, this is largely irrelevant to you, but you may encounter similar declarations in C header files for libraries that try to be compatible with C++. C and C++ can be mixed in a single program, but it requires such declarations for function to nicely work together.
There's probably an #ifdef __cplusplus around this #define; that's a special macro used to indicate compilation by a C++ compiler.
#define YY_DECL extern "C" int yylex();
Define a macro YY_DECL standing for the declaration of a function yylex that has 'C' linkage inside a C++ program, taking no arguments and returning an int.
#define - a preprocessor directive declaring a new variable for the preprocessor. But you know that.
YY_DECL - the name of the variable.
extern "C" - tells the compiler that the following code is pure C. There are a lot of differences between C and C++ and one cannot generally mix C and C++ code. If you include this into declaration, it allows you to use C in C++. EDIT: The code actually not need to be pure C, but it will be linked as such. But the most common usage pattern is to make a C code compatible with C++. Thanks #larsmans for the correction.
int yylex() - a declaration of a function named yylex with undefined number of parameters and return type int
So the whole command assigns a C function declaration to a preprocessor variable.
I'm wondering about the practical use of #undef in C. I'm working through K&R, and am up to the preprocessor. Most of this was material I (more or less) understood, but something on page 90 (second edition) stuck out at me:
Names may be undefined with #undef,
usually to ensure that a routine is
really a function, not a macro:
#undef getchar
int getchar(void) { ... }
Is this a common practice to defend against someone #define-ing a macro with the same name as your function? Or is this really more of a sample that wouldn't occur in reality? (EG, no one in his right, wrong nor insane mind should be rewriting getchar(), so it shouldn't come up.) With your own function names, do you feel the need to do this? Does that change if you're developing a library for others to use?
What it does
If you read Plauger's The Standard C Library (1992), you will see that the <stdio.h> header is allowed to provide getchar() and getc() as function-like macros (with special permission for getc() to evaluate its file pointer argument more than once!). However, even if it provides macros, the implementation is also obliged to provid actual functions that do the same job, primarily so that you can access a function pointer called getchar() or getc() and pass that to other functions.
That is, by doing:
#include <stdio.h>
#undef getchar
extern int some_function(int (*)(void));
int core_function(void)
{
int c = some_function(getchar);
return(c);
}
As written, the core_function() is pretty meaningless, but it illustrates the point. You can do the same thing with the isxxxx() macros in <ctype.h> too, for example.
Normally, you don't want to do that - you don't normally want to remove the macro definition. But, when you need the real function, you can get hold of it. People who provide libraries can emulate the functionality of the standard C library to good effect.
Seldom needed
Also note that one of the reasons you seldom need to use the explicit #undef is because you can invoke the function instead of the macro by writing:
int c = (getchar)();
Because the token after getchar is not an (, it is not an invocation of the function-like macro, so it must be a reference to the function. Similarly, the first example above, would compile and run correctly even without the #undef.
If you implement your own function with a macro override, you can use this to good effect, though it might be slightly confusing unless explained.
/* function.h */
…
extern int function(int c);
extern int other_function(int c, FILE *fp);
#define function(c) other_function(c, stdout);
…
/* function.c */
…
/* Provide function despite macro override */
int (function)(int c)
{
return function(c, stdout);
}
The function definition line doesn't invoke the macro because the token after function is not (. The return line does invoke the macro.
Macros are often used to generate bulk of code. It's often a pretty localized usage and it's safe to #undef any helper macros at the end of the particular header in order to avoid name clashes so only the actual generated code gets imported elsewhere and the macros used to generate the code don't.
/Edit: As an example, I've used this to generate structs for me. The following is an excerpt from an actual project:
#define MYLIB_MAKE_PC_PROVIDER(name) \
struct PcApi##name { \
many members …
};
MYLIB_MAKE_PC_PROVIDER(SA)
MYLIB_MAKE_PC_PROVIDER(SSA)
MYLIB_MAKE_PC_PROVIDER(AF)
#undef MYLIB_MAKE_PC_PROVIDER
Because preprocessor #defines are all in one global namespace, it's easy for namespace conflicts to result, especially when using third-party libraries. For example, if you wanted to create a function named OpenFile, it might not compile correctly, because the header file <windows.h> defines the token OpenFile to map to either OpenFileA or OpenFileW (depending on if UNICODE is defined or not). The correct solution is to #undef OpenFile before defining your function.
Although I think Jonathan Leffler gave you the right answer. Here is a very rare case, where I use an #undef. Normally a macro should be reusable inside many functions; that's why you define it at the top of a file or in a header file. But sometimes you have some repetitive code inside a function that can be shortened with a macro.
int foo(int x, int y)
{
#define OUT_OF_RANGE(v, vlower, vupper) \
if (v < vlower) {v = vlower; goto EXIT;} \
else if (v > vupper) {v = vupper; goto EXIT;}
/* do some calcs */
x += (x + y)/2;
OUT_OF_RANGE(x, 0, 100);
y += (x - y)/2;
OUT_OF_RANGE(y, -10, 50);
/* do some more calcs and range checks*/
...
EXIT:
/* undefine OUT_OF_RANGE, because we don't need it anymore */
#undef OUT_OF_RANGE
...
return x;
}
To show the reader that this macro is only useful inside of the function, it is undefined at the end. I don't want to encourage anyone to use such hackish macros. But if you have to, #undef them at the end.
I only use it when a macro in an #included file is interfering with one of my functions (e.g., it has the same name). Then I #undef the macro so I can use my own function.
Is this a common practice to defend against someone #define-ing a macro with the same name as your function? Or is this really more of a sample that wouldn't occur in reality? (EG, no one in his right, wrong nor insane mind should be rewriting getchar(), so it shouldn't come up.)
A little of both. Good code will not require use of #undef, but there's lots of bad code out there you have to work with. #undef can prove invaluable when somebody pulls a trick like #define bool int.
In addition to fixing problems with macros polluting the global namespace, another use of #undef is the situation where a macro might be required to have a different behavior in different places. This is not a realy common scenario, but a couple that come to mind are:
the assert macro can have it's definition changed in the middle of a compilation unit for the case where you might want to perform debugging on some portion of your code but not others. In addition to assert itself needing to be #undef'ed to do this, the NDEBUG macro needs to be redefined to reconfigure the desired behavior of assert
I've seen a technique used to ensure that globals are defined exactly once by using a macro to declare the variables as extern, but the macro would be redefined to nothing for the single case where the header/declarations are used to define the variables.
Something like (I'm not saying this is necessarily a good technique, just one I've seen in the wild):
/* globals.h */
/* ------------------------------------------------------ */
#undef GLOBAL
#ifdef DEFINE_GLOBALS
#define GLOBAL
#else
#define GLOBAL extern
#endif
GLOBAL int g_x;
GLOBAL char* g_name;
/* ------------------------------------------------------ */
/* globals.c */
/* ------------------------------------------------------ */
#include "some_master_header_that_happens_to_include_globals.h"
/* define the globals here (and only here) using globals.h */
#define DEFINE_GLOBALS
#include "globals.h"
/* ------------------------------------------------------ */
If a macro can be def'ed, there must be a facility to undef.
a memory tracker I use defines its own new/delete macros to track file/line information. this macro breaks the SC++L.
#pragma push_macro( "new" )
#undef new
#include <vector>
#pragma pop_macro( "new" )
Regarding your more specific question: namespaces are often emul;ated in C by prefixing library functions with an identifier.
Blindly undefing macros is going to add confusion, reduce maintainability, and may break things that rely on the original behavior. If you were forced, at least use push/pop to preserve the original behavior everywhere else.