11

Are there any differences in behaviour between the C and C++ preprocessors?

They are defined by different passages of standards text (section 6.10 of the C standard and section 16 of the C++ standard).

My motivation for asking this is that a proposal for making the single quote a digit separator that was recently accepted into C++14 extends the C++ preprocessor grammar to accomodate this change (specifically, it extends the definition of a pp-number), and I'm wondering whether this introduces an incompatibility between the C and C++ preprocessors, and if so, whether it's the first feature to do so.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
HighCommander4
  • 50,428
  • 24
  • 122
  • 194
  • In [GCC](http://gcc.gnu.org/) both `g++` (actually `cc1plus`) and `gcc` (actually `cc1`) use the same `libcpp/` internal library for the preprocessing. – Basile Starynkevitch Feb 02 '14 at 20:13
  • This answer gives some examples of differences that already exist: http://stackoverflow.com/questions/5085533/is-a-c-preprocessor-identical-to-a-c-preprocessor – Bill Lynch Feb 02 '14 at 20:14
  • You could always look at variadic macros. C had them in C99. C++ had to wait until C++11. – chris Feb 02 '14 at 20:26

1 Answers1

8

There are some differences between the C and C++ processors. Ignoring the differences in predefined macros and available system headers, some differences that come to mind in the current versions of C and of C++ are:

  • and and friends are operators, not identifiers, in C++. This means #define and && is valid in C, but not in C++, and means #if 1 and 2 is valid in C++, but not in C (unless and is suitably defined as a macro).
  • false and true are allowed in C++ #if expressions, but replaced by 0 (like all identifiers) in C. This means #if true/C++/#else/C/#endif expands to either C++, or C, depending on the language. Unlike and and friends, though, these are not operators, so may be redefined by #define in either language.
  • ::, .*, and ->* are tokens in C++. As a result of that, the ## operator can be used to form them in C++, but not in C.
  • Raw string literals are available in C++, but not in C. As a result, given a macro foo, R"x("foo")x" expands the macro in C, but not in C++.
  • Hexadecimal floating-point constants are available in C, but not in C++. As a result, given a macro foo, 0x1p+foo expands the macro in C++, but not in C.
  • +1, but are you sure for the floating hex? PP numbers are not necessarily numbers for later phases, no? So floating hex might be valid PP numbers even in C++, but not recognized as numbers, later. Ah, and more important for the keyword/macro issue are probably `bool`, `false` and `true`. – Jens Gustedt Feb 02 '14 at 20:37
  • 2
    @JensGustedt `+` is only allowed as part of a pp-number if it follows `e` or `E` (C++), or `e`, `E`, `p` or `P` (C). If it were unconditionally allowed, `1+2` would be invalid. (`0xE+0xF` is already invalid for the same reason, and that is already somewhat of a problem.) –  Feb 02 '14 at 20:43
  • @JensGustedt BTW, `false` and `true` are good points, but different from `and` because they aren't keywords. Will check for the exact details. –  Feb 02 '14 at 20:46
  • 1
    @hvd: `false` and `true` are keywords in C++ and not in C. – Keith Thompson Feb 02 '14 at 20:48
  • @KeithThompson Oops, I got my terminology wrong. You're right, `false` and `true` are keywords. `and` and friends are not, they're operators. Will edit. –  Feb 02 '14 at 20:51
  • 1
    In C, defining a keyword as a macro name has undefined behavior (N1570 6.4.1p2; it's a "shall" outside a constraint). So a conforming C or C++ preprocessor could just treat keywords as ordinary identifiers (I'm less sure about the C++ rules). – Keith Thompson Feb 02 '14 at 20:51
  • 1
    @hvd: Keywords and operators are not exclusive categories. `sizeof` is a keyword that's used as an operator. `and`, `or`, et al are listed separately from the keywords, but they're "reserved and shall not be used otherwise"; I'm not sure what distinction the Standard is making between these alternative representations and actual keywords. – Keith Thompson Feb 02 '14 at 20:52
  • 1
    @KeithThompson It says "The above tokens (case sensitive) are reserved (in translation phases 7 and 8) for use as keywords, and shall not be used otherwise.", which does allow use otherwise in other translation phases, unless I'm misreading. –  Feb 02 '14 at 20:53
  • 1
    @KeithThompson During preprocessing, there isn't anything that's both an operator and a keyword, is there? `sizeof` is only an operator after preprocessing. –  Feb 02 '14 at 20:59