Date: Sun, 14 Jun 2020 12:59:49 +0200
* Tom Honermann via Liaison:
> Copying the WG21/WG14 liason list. For context, refer to C++
> [cpp.cond]p12 <http://eel.is/c++draft/cpp.cond#12> and the value of
> character literals in conditional preprocessing directives. Quote:
>
>> 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.
>> [ Note: Thus, the constant expression in the following #if directive
>> and if statement ([stmt.if]) is not guaranteed to evaluate to the same
>> value in these two contexts:
>>
>> #if 'z' - 'a' == 25
>> if ('z' - 'a' == 25)
>>
>> — end note
>> ]
The canonical example is probably signed vs unsigned chars. The rule
in the standard allows preprocessing to be independent of that.
On the other hand, one cannot use a simple preprocessor conditional
(such as the '\377' < 0) to tell whether chars are signed or not.
> On 6/11/20 11:40 AM, Corentin via SG16 wrote:
>> There are 3 use cases:
>>
>> * Detect ASCII vs EBCDIC at compile time, using different methods
>> including #if 'A' == '\301'which I am not sure how it works ( a
>> more comment attempt is #if 'A' == 65)
>>
> \301 == 0xC1 == 'A' in EBCDIC code pages.
>>
>> * Comparing with a #define, most frequent pattern being to
>> compare with a path separator, as a means of compile time
>> configuration.
>> * Trying to detect other encodings
I'm pretty sure there are more indirect uses of character constants in
expressions, with constructs like this:
# if defined TIOCGWINSZ && TIOCGSIZE == TIOCGWINSZ
Where these ioctl constants are traditionally defined like this:
#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */
And eventually this expands to something that performs arithmetic on
't'.
> Copying the WG21/WG14 liason list. For context, refer to C++
> [cpp.cond]p12 <http://eel.is/c++draft/cpp.cond#12> and the value of
> character literals in conditional preprocessing directives. Quote:
>
>> 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.
>> [ Note: Thus, the constant expression in the following #if directive
>> and if statement ([stmt.if]) is not guaranteed to evaluate to the same
>> value in these two contexts:
>>
>> #if 'z' - 'a' == 25
>> if ('z' - 'a' == 25)
>>
>> — end note
>> ]
The canonical example is probably signed vs unsigned chars. The rule
in the standard allows preprocessing to be independent of that.
On the other hand, one cannot use a simple preprocessor conditional
(such as the '\377' < 0) to tell whether chars are signed or not.
> On 6/11/20 11:40 AM, Corentin via SG16 wrote:
>> There are 3 use cases:
>>
>> * Detect ASCII vs EBCDIC at compile time, using different methods
>> including #if 'A' == '\301'which I am not sure how it works ( a
>> more comment attempt is #if 'A' == 65)
>>
> \301 == 0xC1 == 'A' in EBCDIC code pages.
>>
>> * Comparing with a #define, most frequent pattern being to
>> compare with a path separator, as a means of compile time
>> configuration.
>> * Trying to detect other encodings
I'm pretty sure there are more indirect uses of character constants in
expressions, with constructs like this:
# if defined TIOCGWINSZ && TIOCGSIZE == TIOCGWINSZ
Where these ioctl constants are traditionally defined like this:
#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */
And eventually this expands to something that performs arithmetic on
't'.
Received on 2020-06-14 06:03:01