Deutsch   English   Français   Italiano  
<v8k4i7$37tvs$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!feeds.phibee-telecom.net!3.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Thiago Adams <thiago.adams@gmail.com>
Newsgroups: comp.lang.c
Subject: Re: What is your opinion about unsigned int u = -2 ?
Date: Fri, 2 Aug 2024 23:27:18 -0300
Organization: A noiseless patient Spider
Lines: 98
Message-ID: <v8k4i7$37tvs$1@dont-email.me>
References: <v8dfo9$1k7cg$1@dont-email.me>
 <pan$d2c8a$8c54ac9f$29a202e0$12c6ce86@invalid.invalid>
 <87bk2cecan.fsf@bsb.me.uk> <v8inds$2qpqh$1@dont-email.me>
 <v8iqnr$7l3c$1@news.xmission.com> <v8irje$2rolg$1@dont-email.me>
 <87r0b6g3qx.fsf@nosuchdomain.example.com> <v8jbj5$2us0r$4@dont-email.me>
 <v8jvln$33atp$1@dont-email.me> <87h6c2fldh.fsf@nosuchdomain.example.com>
 <v8k21v$33nca$1@dont-email.me> <878qxefjk2.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 04:27:20 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="6ca7cab00778520cac37785ddd7f8d1f";
	logging-data="3405820"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18o6UB6SgQBMj0YubSsOq05xexQgNWyPAM="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:0gx83wvFFrtg5ksbdxL6UBCxScI=
Content-Language: en-GB
In-Reply-To: <878qxefjk2.fsf@nosuchdomain.example.com>
Bytes: 4459

Em 8/2/2024 11:04 PM, Keith Thompson escreveu:
> Thiago Adams <thiago.adams@gmail.com> writes:
>> Em 8/2/2024 10:25 PM, Keith Thompson escreveu:
>>> Thiago Adams <thiago.adams@gmail.com> writes:
>>> [...]
>>>> I am doing experiments with constexpr. What happens with overflow in
>>>> compile time? The answer is not so clear. Sometimes it does not
>>>> compile and sometimes it works as in runtime.
>>> Your first example fails due to signed integer overflow.  Your
>>> second
>>> example is well defined because there is no such thing as unsigned
>>> integer overflow.
>>
>> I need a new name other than overflow.
> 
> Wraparound, or unsigned wraparound if you want to be a little more
> precise.
> 
> C23 adds this entry to the glossary (3.28):
> 
>      wraparound
> 
>      the process by which a value is reduced modulo 2^N, where N is the
>      width of the resulting type
> 
> The standard uses a superscript, which I can't easily reproduce here.
> I hope it's sufficiently obvious that I'm not using ^ to mean bitwise xor.
> 
> N3220 6.2.5p11 (same or similar wording appears in earlier editions) :
> 
>      A computation involving unsigned operands can never produce an
>      overflow, because arithmetic for the unsigned type is performed
>      modulo 2^N.
> 
>> The expression
>>
>> ULLONG_MAX*ULLONG_MAX/ULLONG_MAX/ULLONG_MAX
>>
>> has the result 1 if calculated with infinite precision.
>>
>> But the calculated value here is 0
> 
> Right.  The subexpression ULLONG_MAX*ULLONG_MAX in infinite precision
> would be 340282366920938463426481119284349108225 in infinite precision,
> but assuming 64-bit unsigned long long the actual result is that value
> modulo 2^64, or 1.  Dividing 1 by ULLONG_MAX yields 0 (since integer
> division truncates); dividing again by ULLONG_MAX yields 0 again.
> 
> The reduction modulo 2^64 happens on each arithmitic operation (here one
> multiplication and two divisions), not on the expression as a whole.
> Since ULLONG_MAX*ULLONG_MAX is 1 (more precisely 1ull), the expression
>      ULLONG_MAX*ULLONG_MAX/ULLONG_MAX/ULLONG_MAX
> is equivalent to
>      1ull/ULLONG_MAX/ULLONG_MAX
> 
>> #include <stdio.h>
>>
>> int main()
>> {
>>     constexpr unsigned long long ULLONG_MAX = 18446744073709551615;
>>     constexpr unsigned long long r =
>>     ULLONG_MAX*ULLONG_MAX/ULLONG_MAX/ULLONG_MAX;
>>     printf("%llu", r);
>> }
> 

Thanks.
Here a sample with signed int that has a overflow  warning.


#include <stdio.h>

int main()
{
    constexpr int a = 2147483647;
    constexpr int b = 1;
    constexpr int c = a+b;
}

https://godbolt.org/z/ca31r8EMK


I think both cases (overflow and wraparound) should have warnings.

Comparing with __builtin_add_overflow it also reports wraparound.

#include <stdio.h>

int main()
{
    unsigned int r;
    if (__builtin_add_overflow(0,-1, &r) != 0)
    {
      printf("fail");
    }
}