Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: David Brown Newsgroups: comp.lang.c Subject: Re: What is your opinion about unsigned int u = -2 ? Date: Sat, 3 Aug 2024 19:43:14 +0200 Organization: A noiseless patient Spider Lines: 71 Message-ID: References: <87bk2cecan.fsf@bsb.me.uk> <87r0b6g3qx.fsf@nosuchdomain.example.com> <87h6c2fldh.fsf@nosuchdomain.example.com> <878qxefjk2.fsf@nosuchdomain.example.com> <87zfpue3bz.fsf@nosuchdomain.example.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Sat, 03 Aug 2024 19:43:20 +0200 (CEST) Injection-Info: dont-email.me; posting-host="b209585f2ada3beb09365cfb8283ed97"; logging-data="3740878"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/iAuZKhw2luCHpwq6uMp7RdrybSBLmxYE=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:34+2rkAT0/iW18O/BM0OWS1sTqI= Content-Language: en-GB, nb-NO In-Reply-To: <87zfpue3bz.fsf@nosuchdomain.example.com> Bytes: 4039 On 03/08/2024 04:40, Keith Thompson wrote: > Thiago Adams writes: > [...] >> Here a sample with signed int that has a overflow warning. >> >> >> #include >> >> int main() >> { >> constexpr int a = 2147483647; >> constexpr int b = 1; >> constexpr int c = a+b; >> } >> >> https://godbolt.org/z/ca31r8EMK > > It's reasonable to warn about a+b, since it has undefined behavior. > In fact gcc warns about the expression a+b, since it has undefined > behavior, and issues a fatal error message about its use in a context > requiring a constant expression, since that's a constraint violation. > >> I think both cases (overflow and wraparound) should have warnings. > > You're free to think that, of course, but wraparound behavior is well > defined and unambiguous. I wouldn't mind an *optional* warning, but > plenty of programmers might deliberately write something like > > const unsigned int max = -1; > > with the reasonable expectation that it will set max to INT_MAX. > >> Comparing with __builtin_add_overflow it also reports wraparound. >> >> #include >> >> int main() >> { >> unsigned int r; >> if (__builtin_add_overflow(0,-1, &r) != 0) >> { >> printf("fail"); >> } >> } > > Of course __builtin_add_overflow is a non-standard gcc extension. The > documentation says: > > -- Built-in Function: bool __builtin_add_overflow (TYPE1 a, TYPE2 b, > TYPE3 *res) > ... > These built-in functions promote the first two operands into > infinite precision signed type and perform addition on those > promoted operands. The result is then cast to the type the third > pointer argument points to and stored there. If the stored result > is equal to the infinite precision result, the built-in functions > return 'false', otherwise they return 'true'. As the addition is > performed in infinite signed precision, these built-in functions > have fully defined behavior for all argument values. > > It returns true if the result is equal to what would be computed in > infinite signed precision, so it treats both signed overflow and > unsigned wraparound as "overflow". It looks like a useful function, and > if you use it with an unsigned target, it's because you *want* to detect > wraparound. > C23 provides ckd_add() that is identical to __builtin_add_overflow() except for the order of the operands.