Authors: Jay Ghiron
Date: 2026-09-25
Submitted against: C23
Status: Open
This includes interpreting character constants, which can involve converting escape sequences into execution character set members. Whether the numeric value for these character constants matches the value obtained when an identical character constant occurs in an expression (other than within a
#ifor#elifdirective) is implementation-defined. Whether a single-character character constant may have a negative value is implementation-defined.
(C23 6.10.2 "Conditional inclusion" paragraph 13.)
Does this apply to UTF-8 character constants, UTF-16 character constants, and UTF-32 character constants? For example:
#if u'0'!=48
#error
#endif
Can this condition be true and cause an error? Note that C++ removed all wording which allowed character constants in conditional expression inclusion preprocessing directives to be different (see also C++ P2316).
If __STDC_MB_MIGHT_NEQ_WC__ is not defined and the implementation
uses a different encoding in conditional expression inclusion
preprocessing directives for integer character constants and wchar_t
character constants, must the implementation give equivalent values in
conditional expression inclusion preprocessing directives for integer
character constants and wchar_t character constants which both
contain one character which is the same and is in the basic character
set? For example:
#ifndef __STDC_MB_MIGHT_NEQ_WC__
#if'x'!=L'x'
#error
#endif
#endif
Can these conditions be true and cause an error?
If __STDC_MB_MIGHT_NEQ_WC__ is defined, can the implementation give
wchar_t character constants which contain one character in the basic
character set a negative value if they occur outside of conditional
expression inclusion preprocessing directives? For example:
static_assert(L'x'>0);
Can this condition be false and cause an error? Note that C++
requires such wchar_t character constants to have nonnegative
values.
If __STDC_MB_MIGHT_NEQ_WC__ is defined, do the requirements on
decimal digits 0 through 9 being contiguous still apply to
wchar_t character constants which contain one character that is a
decimal digit if they occur outside of conditional expression
inclusion preprocessing directives? For example:
static_assert(L'1'-L'0'==1);
Can this condition be false and cause an error? The same question
would apply in C2Y to the hexadecimal digits a through f, and
separately the hexadecimal digits A through F.
If the implementation uses a different encoding in conditional
expression inclusion preprocessing directives for character constants,
do the same requirements on contiguous ranges of characters (such as
decimal digits 0 through 9) also apply to character constants
within conditional expression inclusion preprocessing directives?
This applies to UTF-8 character constants, UTF-16 character constants,
and UTF-32 character constants if question one is resolved as allowing
different encodings for those character constants when inside of
conditional expression inclusion preprocessing directives. If
question four is resolved as not requiring contiguous ranges with
wchar_t character constants outside of conditional expression
inclusion preprocessing directives when __STDC_MB_MIGHT_NEQ_WC__ is
defined, then this question would not apply to wchar_t character
constants. For example:
#if'1'-'0'!=1
#error
#endif
Can this condition be true and cause an error?
Can a character in the basic character set have a value in char that
is not representable in int? This can only occur with
CHAR_MAX>INT_MAX because of the requirements on char. If so, what
would be the value of an integer character constant that contains such
a character? Note that a negative value might make using it with one
of the <ctype.h> functions undefined. Additionally, if
'0'==INT_MAX is true then the decimal digits being contiguous would
lose meaning since '0'+1=='1' would be undefined.
Character constants, when evaluated in
#ifexpressions, may be interpreted in the source character set, the execution character set, or some other implementation-defined character set. This latitude reflects the diversity of existing practice, especially in cross-compilers.
(Section 6.6 "Constant expressions" paragraph 3 C99 Rationale.)
The intent is to allow the source character set to be used for integer
character constants and wchar_t character constants (other character
constants did not exist in C99), but the source basic character set is
smaller than the execution basic character set. Was it intended that
'\a', '\b', '\n', '\r', and the equivalent wchar_t character
constants must be valid despite the source basic character set not
including them?
If __STDC_MB_MIGHT_NEQ_WC__ is defined, is the encoding of the
execution basic character set in wchar_t not locale-specific? That
is, is L'x' valid for all locales?