Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this C or C++ macro not expanded by the preprocessor?

Can someone points me the problem in the code when compiled with gcc 4.1.0.

#define X 10 int main() {   double a = 1e-X;   return 0; } 

I am getting error:Exponent has no digits.

When I replace X with 10, it works fine. Also I checked with g++ -E command to see the file with preprocessors applied, it has not replaced X with 10. I was under the impression that preprocessor replaces every macro defined in the file with the replacement text with applying any intelligence. Am I wrong?

I know this is a really silly question but I am confused and I would rather be silly than confused :).

Any comments/suggestions?

like image 789
Atul Avatar asked Jun 09 '10 06:06

Atul


People also ask

How are macros expanded in C?

The LENGTH and BREADTH are called the macro templates. The values 10 and 20 are called macro expansions. When the program run and if the C preprocessor sees an instance of a macro within the program code, it will do the macro expansion. It replaces the macro template with the value of macro expansion.

How are macros expanded?

Usually, macros are expanded on behalf of the user as needed. Macro expansion is an integral part of eval and compile . Users can also expand macros at the REPL prompt via the expand REPL command; See Compile Commands.

Are macros removed after preprocessing?

Explanation: True, After preprocessing all the macro in the program are removed.

What is preprocessor expansion?

The preprocessor provides the ability for the inclusion of header files, macro expansions, conditional compilation, and line control. In many C implementations, it is a separate program invoked by the compiler as the first part of translation.


2 Answers

The preprocessor is not a text processor, it works on the level of tokens. In your code, after the define, every occurence of the token X would be replaced by the token 10. However, there is not token X in the rest of your code.

1e-X is syntactically invalid and cannot be turned into a token, which is basically what the error is telling you (it says that to make it a valid token -- in this case a floating point literal -- you have to provide a valid exponent).

like image 113
avakar Avatar answered Oct 08 '22 17:10

avakar


When you write 1e-X all together like that, the X isn't a separate symbol for the preprocessor to replace - there needs to be whitespace (or certain other symbols) on either side. Think about it a little and you'll realize why.. :)

Edit: "12-X" is valid because it gets parsed as "12", "-", "X" which are three separate tokens. "1e-X" can't be split like that because "1e-" doesn't form a valid token by itself, as Jonathan mentioned in his answer.

As for the solution to your problem, you can use token-concatenation:

#define E(X) 1e-##X int main() {   double a = E(10); // expands to 1e-10   return 0; } 
like image 36
tzaman Avatar answered Oct 08 '22 17:10

tzaman