C++ Logo

SG16

Advanced search

Subject: Re: [wg14/wg21 liaison] Characters literals in preprocessor conditionals
From: Bjarne Stroustrup (bjarne_at_[hidden])
Date: 2020-06-14 08:13:41


My rule of thumb is "don't mess with the preprocessor". The odds for
unexpected results are high compared to the likely benefits.

On 6/14/2020 6:59 AM, Florian Weimer via Liaison wrote:
> * Tom Honermann via Liaison:
>
>> Copying the WG21/WG14 liason list.  For context, refer to C++
>> [cpp.cond]p12 <https://urldefense.com/v3/__http://eel.is/c**Adraft/cpp.cond*12__;Kysj!!KwNVnqRv!SlLH7yNwGLi3Ef6XFaur1pfb7D0zKPYSYLQWtXOd1XoItWe2G8EcUA6PwwOVTQ$ > 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'.
> _______________________________________________
> Liaison mailing list
> Liaison_at_[hidden]
> Subscription: https://urldefense.com/v3/__https://lists.isocpp.org/mailman/listinfo.cgi/liaison__;!!KwNVnqRv!SlLH7yNwGLi3Ef6XFaur1pfb7D0zKPYSYLQWtXOd1XoItWe2G8EcUA7QE9KaZA$
> Link to this post: https://urldefense.com/v3/__http://lists.isocpp.org/liaison/2020/06/0093.php__;!!KwNVnqRv!SlLH7yNwGLi3Ef6XFaur1pfb7D0zKPYSYLQWtXOd1XoItWe2G8EcUA4AN5wGQA$


SG16 list run by sg16-owner@lists.isocpp.org