I'm currently trying to understand how the glibc startup routines (__libc_start_main) process Elf Auxiliary vector types (auxv_t).
Browsing through the source code for glibc, I find references to some function named GLRO. In trying to track down the definition for this function, the closest I can find is
#define GLRO(x) _##x
When I search for "##x", all I find is other similar "#define" directives, which leaves me confused. What does this definition mean? Is "##x" some kind of compiler directive?
Kerrek SB's answer provides what it does, but not the macro's purpose. So here it is:
"The GLRO() macro is used to access global or local read-only data, see sysdeps/generic/ldsodefs.h."
Source: http://cygwin.com/ml/libc-help/2012-03/msg00006.html
This is a preprocessor macro.
You can see for yourself what it does by running the preprocessor. Just make a sample file, like this:
// foo.c
#include <some_glibc_header.h>
GLRO(hello)
Now run the preprocessor:
gcc -E foo.c
You'll see that the macro creates a new token by putting an underscore in front of the given token; in our example we obtain _hello. The ## preprocessor operator concatenates tokens.
#define GLRO(x) _##x
## is the token pasting operator and it concatenates its two operands.
e.g., a ## b yields ab and _ ## x yields _x.
So for example:
GLRO(my_symbol) = 0;
would result in:
_my_symbol = 0;
Related
I was trying to build a C project which has a rather unfamiliar way to define namespaces, eg. in file root.h
#define eval CRYPTO_NAMESPACE(eval)
And in the Makefile the following appears (rule for make all):
gcc -O3 -g -march=native -mtune=native -Wall -I. -Isubroutines -DKAT -DKATNUM='cat KATNUM' "-DCRYPTO_NAMESPACE(x)=x" "-D_CRYPTO_NAMESPACE(x)=_##x" -o kat nist/kat_kem.c nist/rng.c benes.c bm.c controlbits.c decrypt.c encrypt.c gf.c operations.c pk_gen.c root.c sk_gen.c synd.c transpose.c util.c -I${PWD}/subroutines -L${PWD}/libs/ -lXKCP -lcrypto -ldl
What do these options do:
"-DCRYPTO_NAMESPACE(x)=x" "-D_CRYPTO_NAMESPACE(x)=_##x"
I know that -DXXX=YYY is the same as #define XXX YYY. Now, why is it in double-quotes? Why it looks like a macro (may be it is)? Lastly, what does _##x mean?
The macro in the header:
#define eval CRYPTO_NAMESPACE(eval)
Replaces every token eval with CRYPTO_NAMESPACE(eval). So if the code contains
void eval(char *expr) {
...
the preprocessor output - without any other definition - would be
void CRYPTO_NAMESPACE(eval)(char *expr) {
...
The -D parameters effectively add two more definitions:
#define DCRYPTO_NAMESPACE(x) x
#define _CRYPTO_NAMESPACE(x) _##x
In our example, the first define causes the normal result to be re-written one more time:
void eval(char *expr) {
...
so we're back where we started. A different definition could be used to change the compiled name of the function. This definition makes the header definition a no-op.
The second macro uses the token concatenation operator ##. It adds a prefix underscore _ to the macro argument. E.g. if the code contained something like:
void _CRYPTO_NAMESPACE(foo)(int x) {
then the result is
void _foo(int x) {
At a higher level, these macros allow names of things (in the first case anything named eval and in the second, any name at all) to be transformed uniformly throughout the program. This is a fairly standard workaround for name collisions in big C programs. If you have two source code bases that have both defined the same public function name, macros like this can be used to add a prefix or suffix that changes one or both names in the compiled code without modifying either original code. This is an important capability for long-term configuration management where manually editing externally furnished code bases isn't a serious option.
A wild guess is that this treatment is given to eval because the likelihood of some other chunk of C also defining a function named eval is extremely high.
I want to use macro parameter like this:
#define D(cond,...) do{ \
#if cond \
#define YYY 1 \
#else \
#define YYY 0 \
} while(0)
Is it possible?
UPD
Maybe when sources will be preprocessed twice: gcc -E source.c | gcc -xc - next will work:
#define D(cond,...) #define YYY cond&DEBUG
#if YYY
#define D(...) printf( __VA_ARGS__ )
#else
#define D(...)
#endif
No, because C 2011 [N1570] 6.10.3.4 3 says, about macro replacement, “The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one,…”
This is not possible. Read about the GNU cpp preprocessor and the C11 standard (i.e. n1570), and check here. The C preprocessor is (conceptually at least) run before the rest of the compiler (which gets the preprocessed form of your translation unit). BTW, for a file foo.c you could use gcc -C -E foo.c > foo.i (using GCC) to get inside foo.i its preprocessed form, and you can inspect that foo.i -since it is a textual file- with a pager or an editor.
However, a .c file can be generated (generating C code is a common practice, at least since the 1980s; for example with yacc, bison, rpcgen, swig, ....; many large software projects use specialized generators of C or C++ code...). You might consider using some other tool, perhaps the GPP preprocessor (or GNU m4) or some other program or script, to generate your C file (from something else). Look also into autoconf (it might have goals similar to yours).
You may want to configure your build automation tool for such purpose, e.g. edit your Makefile for GNU make.
No, this is not possible.
During translation, all preprocessing directives (#define, #include, etc.) are executed before any macro expansion occurs, so if a macro expands into a preprocessing directive, it won't be interpreted as such - it will be interpreted as (invalid) source code.
As pointed out by others this is not possible but there is a work around:
int YYY;
/* global scope variables are sometimes considered bad practice... */
#define D(cond,...) do{ \
if (cond) { \
YYY = 1; \
} \
else { \
YYY = 0; \
} \
} while(0)
Use an optimizing flag (ex: gcc/clang -O3) and it will replace the dead code as if it was a macro. Obviously you may want to change the type of YYY but you seem to use it like a boolean.
No, you cannot. The C preprocessor cannot know what is going to occur during runtime.
The preprocessor goes through the program before it is even compiled and replaces every macro defined with its assigned value.
This is some poor man's code generation, for when integrating another tool to the project is overkill.
Define a macro like this, expanding for your needs:
#define NESTED /* Comment out instead of backslash new lines.
*/ /*
*/ UNDEF REPLACED /*
*/ /*
*/ IFDEF CONDITION /*
*/ DEFINE REPLACED 1 /*
*/ ELSE /*
*/ DEFINE REPLACED 0 /*
*/ ENDIF
Your version of NESTED can be a function-like macro, and REPLACED can have a more elaborated body.
Leave CONDITION and the directive named macros without a definition.
DEFINE CONDITION to control which value NESTED gets on compilation, similarly to normal #ifdef usage:
DEFINE CONDITION
NESTED
int i = REPLACED; //i == 1
UNDEF CONDITION
NESTED
int z = REPLACED; //z == 0
Source code that uses NESTED and the other macros will not compile. To generate a .c or .cpp file that you can compile with your chosen options, do this:
gcc -E -CC source.c -o temporary.c
gcc -E \
-DDEFINE=\#define -DUNDEF=\#undef \
-DIFDEF=\#ifdef -DELSE=\#else -DENDIF=\#endif \
temporary.c -o usableFile.c
rm temporary.c #remove the temporary file
-E means preprocess only, not compile. The first gcc command expands NESTED and all normally defined macros from the source. As DEFINE, IFDEF, etc. are not defined, they and their future arguments remain as literal text in the temporary.c file.
-CC makes the comments be preserved in the output file. After the preprocessor replaces NESTED by its body, temporary.c contains the directive macros in separate lines, with the comments. When the comments are removed on the next gcc command, the line breaks remain by the standard.
# is accepted in the body of a macro that takes no arguments. However, unlike macros, directives are not rescaned and executed on expansion, so you need another preprocessor pass to make nested defines work. All preprocessing related to the delayed defines needs to be delayed too, and made available to the preprocessor at once. Otherwise, directives and arguments needed in a later pass are consumed and removed from the code in a previous one.
The second gcc command replaces the -D macros by the delayed directives, making all of them available to the preprocessor starting on the next pass. The directives and their arguments are not rescaned in the same gcc command, and remain as literal text in usableFile.c.
When you compile usableFile.c, the preprocessor executes the delayed directives.
I'm writing C code which requires me to use multiple function calls of the same definition which differ only by single characters. Is there a way I can make a macro function which takes say a number and can insert these calls into my code for me where I call the macro given I know the numbers at compile time:
i.e.
#define call_pin_macro(X)
enable_pin#X();
do_thing_pin#X();
do_other_thing_pin#X();
.
.
void pin_function(void){
call_pin_macro(1);
call_pin_macro(2);
call_pin_macro(3);
}
Instead of:
void pin_function(void){
enable_pin1();
do_thing_pin1();
do_other_thing_pin1();
enable_pin2();
do_thing_pin2();
do_other_thing_pin2();
enable_pin3();
do_thing_pin3();
do_other_thing_pin3();
}
As a note I have looked at stringification (Hence the included #X's) in gcc however I cannot get the above code to compile which I get an error "error: '#' is not followed by a macro parameter". And it thus it seems this isn't exactly the functionality I am after. Thanks in advance.
In gcc you can do it like this:
#define call_pin_macro(X) \
enable_pin##X(); \
do_thing_pin##X(); \
do_other_thing_pin##X();
The double hash is the macro concatenation operator. You don't want to use stringify because that will put quotes around it.
The backslashes allow you to continue the macro over several lines.
In ruby there's very common idiom to check if current file is "main" file:
if __FILE__ == $0
# do something here (usually run unit tests)
end
I'd like to do something similar in C after reading gcc documentation I've figured that it should work like this:
#if __FILE__ == __BASE_FILE__
// Do stuff
#endif
the only problem is after I try this:
$ gcc src/bitmap_index.c -std=c99 -lm && ./a.out
src/bitmap_index.c:173:1: error: token ""src/bitmap_index.c"" is not valid in preprocessor expressions
Am I using #if wrong?
As summary for future guests:
You cannot compare string using #if
BASE_FILE is the name of file that is being compiled (that Is actually what I wanted).
Best way to do this is to set flag during compilation with -D
in gcc you can use:
#if __INCLUDE_LEVEL__ == 0
or:
if(!__INCLUDE_LEVEL__)
to check if your inside the __BASE_FILE__
Yes, you are misusing #if. It only works on integer constant expressions. But even if you were using if, comparing pointers for equality is never a valid way to compare strings in C.
It seems you can't.
Alternatively, it works perfectly fine on a regular if condition, and gcc can optimize this nicely.
if (!strcmp(__BASE_FILE__, __FILE__)) {
// works.
}
but you can't define new main functions or use other preprocessor tricks. but you could short-circuit main by using static methods, but that's harsh and dirty.
But maybe you shouldn't do it. in Ruby/python, this works because usage of files is done at runtime. in C, all files are to be compiled to be used.
Keep in mind that most build system will build one file at a time, building them as object files, and rebuilding them only when necessary. So
__BASE_FILE__ and __FILE__
will be equals most of the time in sources files, if not always. And i would strongly discourage you to do this in header files.
It's easier to just put your tests in separate files, only linking them when needed.
Yup, as others say, you're misusing it since you can't compare strings that way in C, and especially not in the preprocessor.
The file that defines int main(int argc, char* argv[]) is the main file. There can be only one such function in an executable.
In addition to what others have said (you can't have the C preprocessor compare strings), be careful with __BASE_FILE__ because it may not correspond to your definition of "main" file. __BASE_FILE__ is the name of the file being compiled, so it's always equal to __FILE__ in source files, and only differs in headers and other included files.
In particular, __BASE_FILE__ is not the name of the file which contains the main() function.
If I have a C file foo.c and while I have given -DMACRO=1 as command line option for compilation. However, if within the header file also I have
#define MACRO 2
Which of these will get precedence?
I'm making an assumption of what you're doing, but if you'd like to supply from the command-line a non-default value for that macro, try this for the macro definition:
#ifndef MACRO
#define MACRO 2
#endif
That way if the MACRO has already been defined (via command-line parameter) it will neither be redefined nor result in an error.
The command line options apply ahead of any line read from a file. The file contents apply in the order written. In general, you will get at least a warning if any macro is redefined, regardless of whether the command line is involved. The warning may be silenced if the redefinition doesn't matter, perhaps because both definitions are identical.
The right way to answer a question like this is to build a small test case and try it. For example, in q3965956.c put the following:
#define AAA 2
AAA
and run it through the C preprocessor, perhaps with gcc -E:
C:>gcc -DAAA=42 -E q3965956.c
# 1 "q3965956.c"
# 1 ""
# 1 ""
# 1 "q3965956.c"
q3965956.c:1:1: warning: "AAA" redefined
:1:1: warning: this is the location of the previous definition
2
C:>
You can see from the output that the macro expanded to the value given by the #define in the file. Furthermore, you can see from the sequence of # directives that built-in definitions and the command line were both processed before any content of line 1 of q3965956.c.
Defines are stored in order the compiler sees them, and when the compiler encounters a new macro with the same name, it overwrites the previous macro with the new one (at least this is the case in gcc). GCC will also give you a warning when this happens.
You'll get an error for macro redefinition. Obviously -D gets defined first (before the source file is parsed rather than after) or it would have no use. The #define is then a redefinition.
manual says: first all -D and -U are evaluated in order and then all -includes (under section -D)
best way: try it out.