N
Noob
Hello,
I'm involved in an argument over the following preprocessor code.
The author of the code refuses to acknowledge any problem with it.
(NB: I've considered C89 but am curious of any C99 difference.)
#define AA 5
#define BB 7
#define FOOBAR (AA*BB)
#if FOOBAR > 16
#define FOOBAR 16
#endif
$ gcc -Wall -c temp.c
temp.c:5:1: warning: "FOOBAR" redefined
temp.c:3:1: warning: this is the location of the previous definition
"""
[C89] 3.8.3 Macro replacement
Constraints
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 a macro without use of lparen
(an object-like macro) may be redefined by another #define
preprocessing directive provided that the second definition is an
object-like macro definition and the two replacement lists are
identical.
"""
Thus, redefining FOOBAR is a constraint violation, right?
Thus, gcc must emit a diagnostic, but it is free to proceed.
"""
2.1.1.3 Diagnostics
A conforming implementation shall produce at least one diagnostic
message (identified in an implementation-defined manner) for every
translation unit that contains a violation of any syntax rule or
constraint. Diagnostic messages need not be produced in other
circumstances.
"""
What is the behavior, should the compiler decide not to give up?
Is it undefined? Implementation-defined?
When encountering a redefinition, there are two obvious choice:
1) ignore the new definition, and keep the original definition
2) discard the original definition, and adopt the new definition henceforth
Problem is, if the behavior is not defined by the standard, then
it is unsafe to rely on either behavior...
So, did I misunderstand something, or should I whack the author with
a clue bat?
Are the following solutions valid?
1.
#define AA 5
#define BB 7
#define FOOBAR (AA*BB)
#if FOOBAR > 16
#undef FOOBAR
#define FOOBAR 16
#endif
2.
#define AA 5
#define BB 7
#if AA*BB > 16
#define FOOBAR 16
#else
#define FOOBAR (AA*BB)
#endif
Regards.
I'm involved in an argument over the following preprocessor code.
The author of the code refuses to acknowledge any problem with it.
(NB: I've considered C89 but am curious of any C99 difference.)
#define AA 5
#define BB 7
#define FOOBAR (AA*BB)
#if FOOBAR > 16
#define FOOBAR 16
#endif
$ gcc -Wall -c temp.c
temp.c:5:1: warning: "FOOBAR" redefined
temp.c:3:1: warning: this is the location of the previous definition
"""
[C89] 3.8.3 Macro replacement
Constraints
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 a macro without use of lparen
(an object-like macro) may be redefined by another #define
preprocessing directive provided that the second definition is an
object-like macro definition and the two replacement lists are
identical.
"""
Thus, redefining FOOBAR is a constraint violation, right?
Thus, gcc must emit a diagnostic, but it is free to proceed.
"""
2.1.1.3 Diagnostics
A conforming implementation shall produce at least one diagnostic
message (identified in an implementation-defined manner) for every
translation unit that contains a violation of any syntax rule or
constraint. Diagnostic messages need not be produced in other
circumstances.
"""
What is the behavior, should the compiler decide not to give up?
Is it undefined? Implementation-defined?
When encountering a redefinition, there are two obvious choice:
1) ignore the new definition, and keep the original definition
2) discard the original definition, and adopt the new definition henceforth
Problem is, if the behavior is not defined by the standard, then
it is unsafe to rely on either behavior...
So, did I misunderstand something, or should I whack the author with
a clue bat?
Are the following solutions valid?
1.
#define AA 5
#define BB 7
#define FOOBAR (AA*BB)
#if FOOBAR > 16
#undef FOOBAR
#define FOOBAR 16
#endif
2.
#define AA 5
#define BB 7
#if AA*BB > 16
#define FOOBAR 16
#else
#define FOOBAR (AA*BB)
#endif
Regards.