1

I was under the impression that #define and #include can be written anywhere in our code, as long as they don't produce any syntax errors when the pre-processor processes the macros before it is fetched to the compiler.

I ran the following code:

#include <stdio.h> int main(void) { int B = A; #define A 4 printf("%d", B); return 0; } 

and it produced the following error:

prog.c: In function 'main': prog.c:4:13: error: 'A' undeclared (first use in this function) int B = A; ^ prog.c:4:13: note: each undeclared identifier is reported only once for each function it appears in

But when I do this, it works!

#include <stdio.h> int main(void) { #define A 4 int B = A; printf("%d", B); return 0; } 

Not sure what am I missing here, but why does compiler give such an error "undeclared A"?

Is it so that when pre-processor reads the line #define A 4 it will start replacing any A with 4 from the subsequent lines of code?

1
  • 1
    No. It definitely matters where you put your preprocessor directives. Also, while being compile-time error-free is a necessary condition for a valid program, it certainly is not a sufficient one. Commented Jan 3, 2017 at 7:31

4 Answers 4

11

C files are parsed top to bottom at both the preprocessing stage and the compilation stage. (Note: As MSalters points out, each stage starts separately at the top).

The preprocessor won't replace A until it has seen that token defined.

Is it so that when pre-processor reads the line #define A 4 it will start replacing any A with 4 from the subsequent lines of code?

Yes. You aren't missing much.

Sign up to request clarification or add additional context in comments.

2 Comments

Perhaps to make it explicit: the preprocessing stage runs from top to bottom, and only then does the compilation stage start at the top.
@MSalters - Added it in. Thanks for the improvement suggestion.
1

The position of the preprocessing directives does not matter, as the preprocessor does not know about C syntax.

The preprocessor (i.e. the 4th stage in the analysis of a file) can also preprocess other languages.

A preprocessing line starts with spaces followed by #. All the lines that do not start so are considered text code lines.

It is common to include #define inside the function when you choose different parameters depending on some condition, for example

f( #if cond1 a #elif cond2 b #else c #endif ) 

or you can use #include to initialize an array like that

int[] a = { #include data-file } 

or you can change the syntax depending on some condition using #define. for example, when arch is true, static keyword static is not considered:

f() { #if arch #define static #endif static int x; ... #undef static } 

The #define will insert the object macro static in the environment of the preprocessor having the value nil and this object is valid between the lines #define static and #undef.

In your case, you define the variable A after you use it, 1 line before.

Comments

0

No. You can define and undefine wherever you feel like doing so. However you need to define your macros before using them. You have used your macro before declaring it.

The preprocessor have no "crystal ball", nor it does lookahead. If you defined a macro, that macro will be valid from that point until the end of file or the #undef token is found.

Comments

-2

you have defined 'A' in curly brackets so the life of 'A' will be limited only for that braces(only for main loop).In braces code executes sequentially and you are using 'A' before define.

1 Comment

Your first statement is wrong. The preprocess does not know about C scope. ideone.com/EMXxyN

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.