Path: csiph.com!news.mixmin.net!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: Are there any conformant C compilers?
Date: Tue, 13 Sep 2022 17:24:15 -0700
Organization: A noiseless patient Spider
Lines: 75
Message-ID: <86bkriolao.fsf@linuxsc.com>
References: <87zgfqk9l4.fsf@nosuchdomain.example.com> <413ae987-3216-415f-88cf-8a6a0f7cfe4an@googlegroups.com> <68fbf792-a971-4e42-af84-c02257625abdn@googlegroups.com> <87ilmcyuv3.fsf@bsb.me.uk> <86illspz8y.fsf@linuxsc.com> <0TGTK.472157$BKL8.553@fx15.iad>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader01.eternal-september.org; posting-host="e4a07c6eb40a7dcf36ed28254bbf399a"; logging-data="2851874"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+6ie7XiLPUP6Esx+PJcDSzc+essJjQ+l8="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:gIvlVa+ihWm5jH4bD7tVxwrV4hs= sha1:E2w61FghKea2VVaLemB+CGBf04w=
Xref: csiph.com comp.lang.c:167692
scott@slp53.sl.home (Scott Lurndal) writes:
> Tim Rentsch writes:
>
>> Ben Bacarisse writes:
>>
>>> Thiago Adams writes:
>>>
>>>> An interesting exercise is to think about true and false as
>>>> constexpr. Imagine we have bool in the language but we don't
>>>> have true and false constants.
>>>>
>>>> Then we declare:
>>>>
>>>> constexpr bool true = 1;
>>>> constexpr bool false = 0;
>>>
>>> In this hypothetical situation, presumably 1 and 0 are the actual
>>> values that bool objects represent. If not, this would be a
>>> constraint violation as the standard is deliberately strict about
>>> constexpr initialisers: they undergo no conversions.
>>>
>>> It's not 100% clear to me if, in the finished C23,
>>>
>>> constexpr bool my_bool = 1;
>>>
>>> will be permitted. I think not.
>>
>> I agree with (what I think is) your conclusion that the latest C23
>> draft standard (n3047) deems the initializing expression of
>> my_bool a constraint violation.
>>
>> However, I do not think that n3047 disallows all conversions (that
>> are implicit; AFAICS casting is always allowed). My understanding
>> is that implicit conversions are allowed provided they do not
>> cause a change of abstract value. For example, a definition such
>> as
>>
>> constexpr unsigned int unsigned_one = 1;
>>
>> would be allowed, because the conversion from int to unsigned int
>> does not change the abstract value 1. But the definition of
>> my_bool above is not allowed, because the implicit conversion from
>> int to bool changes the abstract value 1 to the abstract value
>> true. Similarly a definition such as
>>
>> constexpr unsigned int all_ones = -1;
>
> Wouldn't it be more natural to write
>
> constexpr unsigned int all_ones = ~1;
One, using ~0 as the initializing expression has the same
constraint violation as -1 does.
Two, it may be more common for beginners to write ~0u, but
hopefully that is something they outgrow as they gain experience
with C's rules for conversions, and other experience. There are
various expressions that might be used: ~0u, -1u, ~(unsigned)0,
0u-1, etc. All of these choices have the same problem: they are
brittle by virtue of giving a redundant specification of type.
Change the type of the declaration and the initializing
expression can have a wrong value. By contrast using -1 works
whether the variable being declared is an unsigned char, unsigned
short, unsigned int, unsigned long, unsigned long long, uint47_t,
uint_least29_t, size_t, uintmax_t, or any other unsigned type.
Code that is less brittle is better.
> I'd never use your suggestion in real code; I've seen programmers
> do it, but it has never been proper.
It has always been proper. Apparently what is lacking is some
programmers' understanding of C's conversion rules and an
appreciation for writing code that always works rather than
writing code that is brittle.