GCC quietly accepts the following: #define A a #define B a #if #A == #B #endif but it should not, because '#A == #B' is not an integer constant expression, see C99 section 6.10.1 paragraph 1. GCC does properly diagnose #if "a" == "a"
GCC should already reject the use of the # operator, which is only allowed in the replacement list of a macro and then only when followed by a macro parameter.
Documented behaviour.
Still a bug, even if a documented one; the syntax does not allow it. '#if #A' is neither an if-group (because '#A' is not syntactically a constant-expression in the preprocessor) nor a sequence of group-parts, because 'if' is not a non-directive; see 6.10 paragraph 1. Since this a syntax violation, a diagnostic is required. Where is it documented?
*Note (cpp)Assertions::.
Subject: Re: New: #if #A == #B should have a diagnostic On Jun 23, 2005, at 10:04 PM, geoffk at gcc dot gnu dot org wrote: > GCC quietly accepts the following: > > #define A a > #define B a > #if #A == #B > #endif In fact if we look at the output for the following code: #define A b #define B c #if #A == #B void g(void); #endif We find that "void g(void);" is always outputted so in fact it does not do what David wanted it to do. Thanks, Andrew Pinski
Yup, it's documented. However, it's still silently accepted even with -pedantic, and the language doesn't permit that.
(In reply to comment #6) > Yup, it's documented. However, it's still silently accepted even with -pedantic, and the language doesn't > permit that. My copy of the standard only requires a constant expression - can you point out where you read its requiring an integer constant expression? The standard explicitly permits extensions to constant expressions. Since this extension is explicitly documented as for use in #if expressions, it should be obvious that we intend #foo as a constant expression. No diagnostic is therefore required.
The standard does not allow to extend the syntax. Since this violates the syntax of the language a diagnostic is required.
Subject: Re: #if #A == #B should have a diagnostic in ISO C mode On Fri, 24 Jun 2005, neil at gcc dot gnu dot org wrote: > My copy of the standard only requires a constant expression - can you point out > where you read its requiring an integer constant expression? 6.10.1#1, "shall be an integer constant expression"; 6.8.1 in C90. > The standard explicitly permits extensions to constant expressions. Since this But not to integer constant expressions (at least according to the view expressed in the DR#312 discussion in the draft Lillehammer minutes, although DR#032 implies a different view).
Subject: Re: #if #A == #B should have a diagnostic in ISO C mode On 24/06/2005, at 6:24 PM, neil at gcc dot gnu dot org wrote: > > ------- Additional Comments From neil at gcc dot gnu dot org > 2005-06-24 22:24 ------- > (In reply to comment #6) > > > > > >> Yup, it's documented. However, it's still silently accepted even >> with >> >> >> >> >> > -pedantic, and the language doesn't > > > > > >> permit that. >> >> >> >> >> > > My copy of the standard only requires a constant expression - can > you point out > where you read its requiring an integer constant expression? > > > > My copy of C99 says, in 6.10.1 paragraph 1, The expression that controls conditional inclusion shall be an integer constant expression except that: it shall not contain a cast; identifiers (including those lexically identical to keywords) are interpreted as described below; and it may contain unary operator expressions of the form ... It doesn't appear to have changed in TC1 or TC2. > The standard explicitly permits extensions to constant > expressions. Since this > extension is explicitly documented as for use in #if expressions, > it should be > obvious that we intend #foo as a constant expression. No > diagnostic is > therefore required. > > > > I doubt that that was intended to allow things to be constant- expressions which are not syntactically allowed to be expressions...
Created attachment 9148 [details] smime.p7s
Diagnostic needed for -pedantic (and in general I don't like extensions not being diagnosed with -pedantic even where diagnostics aren't strictly required). [comment#10 did not appear on gcc-bugs - apparently substantive messages should not be sent to gcc-bugzilla with signatures or other attachments.]
I am testing a patch for this. It pedwarns on '#foo' in an expression, and also when #assert or #unassert is used. It also warns about these when -Wdeprecated is given.
Subject: Bug number PR preprocessor/22168 A patch for this bug has been added to the patch tracker. The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-12/msg01853.html
*** Bug 11051 has been marked as a duplicate of this bug. ***
*** Bug 35312 has been marked as a duplicate of this bug. ***
Subject: Bug 22168 Author: tromey Date: Tue May 13 14:50:27 2008 New Revision: 135264 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=135264 Log: libcpp PR preprocessor/22168: * include/cpplib.h (struct cpp_options) <objc>: Update documentation. * expr.c (eval_token): Warn for use of assertions. * directives.c (directive_diagnostics): Warn about extensions. (DEPRECATED): New define. (DIRECTIVE_TABLE): Use it. gcc PR preprocessor/22168: * doc/cpp.texi (Top): Update menu. (Alternatives to Wrapper #ifndef): New node. (Other Directives): Document deprecation. (Obsolete Features): Remove menu. (Assertions): Merge node into Obsolete Features. (Obsolete once-only headers): Move earlier; rename to Alternatives to Wrapper #ifndef. * doc/cppopts.texi: Update. * c.opt (Wdeprecated): Enable for C and ObjC. * doc/invoke.texi (Option Summary): Move -Wno-deprecated. (C++ Dialect Options): Move -Wno-deprecated from here to... (Warning Options): ... here. gcc/testsuite PR preprocessor/22168: * gcc.dg/pch/import-2.hs: Add -Wno-deprecated. * gcc.dg/pch/import-1.hs: Add -Wno-deprecated. * gcc.dg/pch/import-2.c: Add -Wno-deprecated. * gcc.dg/pch/import-1.c: Add -Wno-deprecated. * gcc.dg/cpp/import2.c: Add -Wno-deprecated. * gcc.dg/cpp/import1.c: Add -Wno-deprecated. * gcc.dg/cpp/trad/assert3.c: Add -Wno-deprecated. * gcc.dg/cpp/trad/assert2.c: Add -Wno-deprecated. * gcc.dg/cpp/trad/assert1.c: Add -Wno-deprecated. * gcc.dg/cpp/ident.c: Add -Wno-deprecated. * gcc.dg/cpp/ident-1.c: Add -Wno-deprecated. * gcc.dg/cpp/extratokens.c: Add -Wno-deprecated. * gcc.dg/cpp/assert3.c: Add -Wno-deprecated. * gcc.dg/cpp/assert2.c: Add -Wno-deprecated. * gcc.dg/cpp/assert1.c: Add -Wno-deprecated. * gcc.dg/cpp/assert4.c: Compile with -ansi and not -pedantic. Add -Wno-deprecated. * gcc.dg/cpp/pr22168.c: New file. * gcc.dg/cpp/pr22168-2.c: New file. Added: trunk/gcc/testsuite/gcc.dg/cpp/pr22168-2.c trunk/gcc/testsuite/gcc.dg/cpp/pr22168.c Modified: trunk/gcc/ChangeLog trunk/gcc/c.opt trunk/gcc/doc/cpp.texi trunk/gcc/doc/cppopts.texi trunk/gcc/doc/invoke.texi trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.dg/cpp/assert1.c trunk/gcc/testsuite/gcc.dg/cpp/assert2.c trunk/gcc/testsuite/gcc.dg/cpp/assert3.c trunk/gcc/testsuite/gcc.dg/cpp/assert4.c trunk/gcc/testsuite/gcc.dg/cpp/extratokens.c trunk/gcc/testsuite/gcc.dg/cpp/ident-1.c trunk/gcc/testsuite/gcc.dg/cpp/ident.c trunk/gcc/testsuite/gcc.dg/cpp/import1.c trunk/gcc/testsuite/gcc.dg/cpp/import2.c trunk/gcc/testsuite/gcc.dg/cpp/trad/assert1.c trunk/gcc/testsuite/gcc.dg/cpp/trad/assert2.c trunk/gcc/testsuite/gcc.dg/cpp/trad/assert3.c trunk/gcc/testsuite/gcc.dg/pch/import-1.c trunk/gcc/testsuite/gcc.dg/pch/import-1.hs trunk/gcc/testsuite/gcc.dg/pch/import-2.c trunk/gcc/testsuite/gcc.dg/pch/import-2.hs trunk/libcpp/ChangeLog trunk/libcpp/directives.c trunk/libcpp/expr.c trunk/libcpp/include/cpplib.h
Fixed on trunk. I think we're unlikely to backport this, so I'm closing it.