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"); } }