Abhishek Jaiswal
Abhishek Jaiswal

Reputation: 308

Is it erroneous to reuse #define for the same identifier in c?

The K&R book author says that

A second #define for the same identifier is erroneous unless the second token sequence is identical to the first.

But when i tried , the compiler didn't raise any error. So, Can you please elaborate what does the author want to say?

Upvotes: 2

Views: 137

Answers (1)

paxdiablo
paxdiablo

Reputation: 881313

If you did what you say you did, it very much should have raised an diagnostic message. From the relevant section, C11 6.10.3 Macro replacement:

Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, ordering, spelling, and white-space separation, where all white-space separations are considered identical.

An identifier currently defined as an object-like macro shall not be redefined by another #define preprocessing directive unless the second definition is an object-like macro definition and the two replacement lists are identical. Likewise, an identifier currently defined as a function-like macro shall not be redefined by another #define preprocessing directive unless the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical.

See, for example, the following transcript:

pax:/paxhome> cat prog.c
#define X 7
#define X 99

int main(void) { return 99; }

pax:/paxhome> gcc --std=c17 prog.c -o prog
prog.c:2: warning: "X" redefined
    2 | #define X 99
      |
prog.c:1: note: this is the location of the previous definition
    1 | #define X 7
      |

Keep in mind the definition of "identical" given in that first paragraph, they don't have to be exactly the same on a character by character basis. The following two can be considered identical based on the rules given:

#define X 7 + 2
#define X \
    7 \
        + \
            2

Also keep in mind that gcc is treating this as a warning rather than an error. The standard itself only states that a diagnostic message must be generated for invalid programs but also contains the following footnote (my emphasis):

Of course, an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. It may also successfully translate an invalid program.

So gcc is within its rights to simply warn you but compile the program anyway. If you wanted to treat warnings as errors (which is something I tend to prefer for my own code), you can always add the -Werror flag to your compile command (or possibly -Wpedantic -pedantic-errors, depending on your needs).

Upvotes: 1

Related Questions