Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does preprocessing work in this snippet?

#include<stdio.h>
#define A -B
#define B -C
#define C 5

int main() {
  printf("The value of A is %dn", A); 
  return 0;
} 

I came across the above code. I thought that after preprocessing, it gets transformed to

// code from stdio.h

int main() {
  printf("The value of A is %dn", --5); 
  return 0;
}

which should result in a compilation error. But, the code compiles fine and produces output 5.

How does the code get preprocessed in this case so that it does not result into a compiler error?

PS: I am using gcc version 8.2.0 on Linux x86-64.

like image 516
tonystark Avatar asked Aug 09 '18 17:08

tonystark


People also ask

What is meaning of preprocessing?

: to do preliminary processing of (something, such as data) Other Words from preprocess Example Sentences Learn More About preprocess.

Is it preprocessing or pre processing?

pre processing and post processing do not exist. It is preprocessing and postprocessing (with pre-processing and post-processing listed as alternative spellings).


1 Answers

The preprocessor is defined as operating on a stream of tokens, not text. You have to read through all of sections 5.1.1, 6.4, and 6.10 of the C standard to fully understand how this works, but the critical bits are in 5.1.1.1 "Phases of translation": in phase 3, the source file is "decomposed into preprocessing tokens"; phases 4, 5, and 6 operate on those tokens; and in phase 7 "each preprocessing token is converted into a token". That indefinite article is critical: each preprocessing token becomes exactly one token.

What this means is, if you start with this source file

#define A -B
#define B -C
#define C 5
A

then, after translation phase 4 (macro expansion, among other things), what you have is a sequence of three preprocessing tokens,

<punctuator: -> <punctuator: -> <pp-number: 5>

and at the beginning of translation phase 7 that becomes

TK_MINUS TK_MINUS TK_INTEGER:5

which is then parsed as the expression -(-(5)) rather than as --(5). The standard offers no latitude in this: a C compiler that parses your example as --(5) is defective.

When you ask a compiler to dump out preprocessed source as text, the form of that text is not specified by the standard; typically, what you get has whitespace inserted as necessary so that a human will understand it the same way translation phase 7 would have.

like image 128
zwol Avatar answered Oct 18 '22 01:10

zwol