Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it valid to use boolean literals in preprocessor conditionals?

Consider the following code, which results in the boolean literal true being evaluated in a preprocessor conditional:

#define SOME_MACRO true

int main ()
{
#if SOME_MACRO
  return 1;
#else
  return 0;
#endif
}

Clang 3.4 and GCC 4.8 both accept this code, even with -pedantic -std=c++11 -Wall -Wextra.

Visual Studio 2013 rejects it, with fatal error C1017: invalid integer constant expression.

My reading of n3376 § 16.1 is that the regular C++ rules for evaluating constant expressions should apply.

If so, this code is valid, and it's a bug if MSVC does not accept it.

But I don't find the standardeze particularly clear. Could someone confirm this?

like image 684
toojays Avatar asked Jun 02 '14 03:06

toojays


1 Answers

Yes, it is valid. See C++11 §16.1/4 (emphasis mine)

Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text. If the token defined is generated as a result of this replacement process or use of the defined unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined. After all replacements due to macro expansion and the defined unary operator have been performed, all remaining identifiers and keywords, except for true and false, are replaced with the pp-number 0, and then each preprocessing token is converted into a token. The resulting tokens comprise the controlling constant expression which is evaluated according to the rules of 5.19 using arithmetic that has at least the ranges specified in 18.3. For the purposes of this token conversion and evaluation all signed and unsigned integer types act as if they have the same representation as, respectively, intmax_t or uintmax_t (18.4). This includes interpreting character literals, which may involve converting escape sequences into execution character set members. Whether the numeric value for these character literals matches the value obtained when an identical character literal occurs in an expression (other than within a #if or #elif directive) is implementation-defined. Also, whether a single-character character literal may have a negative value is implementation-defined. Each subexpression with type bool is subjected to integral promotion before processing continues.

like image 117
Brian Bi Avatar answered Nov 14 '22 22:11

Brian Bi