Deutsch English Français Italiano |
<v930ut$4mni$2@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!feeds.phibee-telecom.net!news.mixmin.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: how cast works? Date: Thu, 8 Aug 2024 14:57:48 -0300 Organization: A noiseless patient Spider Lines: 136 Message-ID: <v930ut$4mni$2@dont-email.me> References: <v8vlo9$2oc1v$1@dont-email.me> <slrnvb7kis.28a.dan@djph.net> <v929ah$3u7l7$1@dont-email.me> <v92gt1$e1l$1@dont-email.me> <20240808193203.00006287@yahoo.com> <v92va5$4msg$1@dont-email.me> <v930ga$4mni$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Thu, 08 Aug 2024 19:57:49 +0200 (CEST) Injection-Info: dont-email.me; posting-host="c24a25e0e0574963f5160c2b1c68553a"; logging-data="154354"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+bfU6WTNHZmUGcakrUfhcgjoTRwFpqRz8=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:OnGIWIAnLRdbnqrW4exQmJTIfMM= Content-Language: en-US In-Reply-To: <v930ga$4mni$1@dont-email.me> Bytes: 5386 On 08/08/2024 14:50, Thiago Adams wrote: > On 08/08/2024 14:29, Bart wrote: >> On 08/08/2024 17:32, Michael S wrote: >> > On Thu, 8 Aug 2024 14:23:44 +0100 >> > Bart <bc@freeuk.com> wrote: >> >> Try godbolt.org. Type in a fragment of code that does different kinds >> >> of casts (it needs to be well-formed, so inside a function), and see >> >> what code is produced with different C compilers. >> >> >> >> Use -O0 so that the code isn't optimised out of existence, and so >> >> that you can more easily match it to the C ource. >> >> >> >> >> > >> > >> > I'd recommend an opposite - use -O2 so the cast that does nothing >> > optimized away. >> > >> > int foo_i2i(int x) { return (int)x; } >> > int foo_u2i(unsigned x) { return (int)x; } >> > int foo_b2i(_Bool x) { return (int)x; } >> > int foo_d2i(double x) { return (int)x; } >> The OP is curious as to what's involved when a conversion is done. >> Hiding or eliminating code isn't helpful in that case; the results can >> also be misleading: >> >> Take this example: >> >> void fred(void) { >> _Bool b; >> int i; >> i=b; >> } >> >> Unoptimised, it generates this code: >> >> push rbp >> mov rbp, rsp >> >> mov al, byte ptr [rbp - 1] >> and al, 1 >> movzx eax, al >> mov dword ptr [rbp - 8], eax >> >> pop rbp >> ret >> >> You can see from this that a Bool occupies one byte; it is masked to >> 0/1 (so it doesn't trust it to contain only 0/1), then it is widened >> to an int size. >> >> With optimisation turned on, even at -O1, it produces this: >> >> ret >> >> That strikes me as rather less enlightening! >> >> Meanwhile your foo_b2i function contains this optimised code: >> >> mov eax, edi >> ret >> >> The masking and widening is not present. Presumably, it is taking >> advantage of the fact that a _Bool argument will be converted and >> widened to `int` at the callsite even though the parameter type is >> also _Bool. So the conversion has already been done. >> >> You will see this if writing also a call to foo_b2i() and looking at >> the /non-elided/ code. >> >> The unoptimised code for foo_b2i is pretty awful (like masking twice, >> with a pointless write to memory between them). But sometimes with gcc >> there is no sensible middle ground between terrible code, and having >> most of it eliminated. >> >> The unoptimised code from my C compiler for foo_b2i, excluding >> entry/exit code, is: >> >> movsx eax, byte [rbp + foo_b2i.x] >> >> My compiler assumes that a _Bool type already contains 0 or 1. >> >> >> > > If you are doing constant expression in your compiler, then you have the > same problem (casts) I am solving in cake. > > For instance > static_assert((unsigned char)1234 == 210); > > is already working in my cake. I had to simulate this cast. > > Previously, I was doing all computations with bigger types for constant > expressions. Then I realize compile time must work as the runtime. > > For constexpr the compiler does not accept initialization invalid types. > for instance. > > constexpr char s = 12345; > > <source>:6:21: error: constexpr initializer evaluates to 12345 which is > not exactly representable in type 'const char' > 6 | constexpr char s = 12345; > > > I am also checking all wraparound and overflow in constant expressions. > I have a warning when the computed value is different from the math value. > > > > Cake also transpiles C99 to C89. Currently I am changing _Bool to unsigned char. But the values are not converted. For instance: //C99 _Bool b = 123; //C89 unsigned char b = !!(123); This part !! is missing at current implementation. Think in how it could be done. I think this also explain why bool was not on the first versions of C.