Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Preprocessor doesn't process define as expected

I'm having problems with cpp Preprocessor. I have this Input.h file like this:

#ifndef PLATFORM_MOBILE1111
    #define MyTest WEB111
#endif 

int MyTest;

I process it with this command (on OSX):

cpp -E -P Source/Input.h Generated/Output.h

I get this:

    #define MyTest WEB111


int MyTest;

i.e. macro MyTest is not getting applied. Why?


After a bunch of experimentation, I found that if I insert an empty line, variable definition, a comment or any other line after #ifndef line - then it works fine.

#ifndef PLATFORM_MOBILE1111

    #define MyTest WEB111
#endif 

int MyTest;

So the input above gets processed correctly into:

int WEB111;

Can someone explain to me why that is happening? and how to solve that? Is there an option that I can pass?


Edit: I also found that ## (concatenation operator) doesn't work too!

like image 784
Paulius Liekis Avatar asked Sep 01 '17 13:09

Paulius Liekis


People also ask

What is the use of #define preprocessor in C?

#define is a preprocessor directive that is used to define macros in a C program. #define is also known as a macros directive. #define directive is used to declare some constant values or an expression with a name that can be used throughout our C program.

What is C preprocessor explain any two C preprocessor commands with example?

Preprocessors Examples Use #define for constants to increase readability. These directives tell the CPP to get stdio. h from System Libraries and add the text to the current source file. The next line tells CPP to get myheader.

What are preprocessor definitions?

In computer science, a preprocessor (or precompiler) is a program that processes its input data to produce output that is used as input to another program. The output is said to be a preprocessed form of the input data, which is often used by some subsequent programs like compilers.


2 Answers

Strange! You clearly found a bug in the clang preprocessor!

I can reproduce this as well (Apple LLVM version 8.1.0 (clang-802.0.42)) on OSX.

This also starts working as expected when you remove the spaces before #define (indentation), but leading spaces should not matter at all, and a lot of editors indent #defines inside #ifdefs.

One hint on what is going on is that in the bogus versions the #define is still present in the processed source code, while in the correct version it is not. So apparently the preprocessor did not recognize the #define as such at all.

Even this fails (note the leading space):

 #define MyTest WEB111
int MyTest;

While this works as expected:

#define MyTest WEB111
int MyTest;

And this results in WEB222:

 #define MyTest WEB111
 #define MyTest WEB222
int MyTest;

While this results in WEB111:

#define MyTest WEB111
 #define MyTest WEB222
int MyTest;

Crazy!1!! :-)

It seems that always the first indented #define gets ignored.

Now the 'solution': Use:

gcc -E Source/Input.cpp -P -o Generated/Output.cpp

This works as expected, although it is using the same LLVM.

So I assume the gcc executable initializes the preprocessor differently than the cpp. This is still a bug in cpp.

like image 94
Johannes Overmann Avatar answered Oct 12 '22 20:10

Johannes Overmann


I found out that running preprocessor through c++ rather than cpp solves both of my problems:

c++ -E -P Source/Input.h Generated/Output.h

BTW.: you need to add -x c++ flag if you file is not using regular c/c++ extention for c++ command. cpp works fine without that.

like image 36
Paulius Liekis Avatar answered Oct 12 '22 19:10

Paulius Liekis