Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gcc preprocessor and pasting

Tags:

c++

c

gcc

I found this snippet on stackoverflow the other day (thanks for that):

#define PLATFORM 3
#define PASTER(x,y) x ## _ ## y
#define EVALUATOR(x,y)  PASTER(x,y)
#define PLATFORMSPECIFIC(fun) EVALUATOR(fun, PLATFORM)

extern void PLATFORMSPECIFIC(somefunc)(char *x);

Compiled with gcc -E, it results in:

# 1 "xx.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "xx.c"





extern void somefunc_3(char *x);

However:

#define PLATFORM linux
#define PASTER(x,y) x ## _ ## y
#define EVALUATOR(x,y)  PASTER(x,y)
#define PLATFORMSPECIFIC(fun) EVALUATOR(fun, PLATFORM)

extern void PLATFORMSPECIFIC(somefunc)(char *x);

results in:

# 1 "xx.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "xx.c"





extern void somefunc_1(char *x);

What can I do to make this return 'somefunc_linux' ?. Clang seems to do it right, btw.

like image 813
KJH Avatar asked Apr 28 '14 19:04

KJH


People also ask

What is ## in preprocessor?

This is called token pasting or token concatenation. The ' ## ' preprocessing operator performs token pasting. When a macro is expanded, the two tokens on either side of each ' ## ' operator are combined into a single token, which then replaces the ' ## ' and the two original tokens in the macro expansion.

What does the GCC preprocessor do?

The preprocessor outputs one make rule containing the object file name for that source file, a colon, and the names of all the included files, including those coming from -include or -imacros command-line options.

What does ## do in a macro?

The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.

What is a preprocessor token?

Preprocessing tokens (pp-tokens) are a superset of regular tokens. Preprocessing tokens allow the source file to contain non-token character sequences that constitute valid preprocessing tokens during translation. There are four categories of preprocessing tokens: Header filenames, meant to be taken as a single token.


1 Answers

If you want to use linux as a name, you can change your compiler options to undefine it:

gcc -Ulinux

or to be standards compliant:

gcc -std=c90 -pedantic ... # or -std=c89 or -ansi
gcc -std=c99 -pedantic
gcc -std=c11 -pedantic

See more discussion about why here: Why does the C preprocessor interpret the word "linux" as the constant "1"?

like image 169
mbonneau Avatar answered Oct 16 '22 18:10

mbonneau