Warning: mysqli::__construct(): (HY000/1203): User howardkn already has more than 'max_user_connections' active connections in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\includes\artfuncs.php on line 21
Failed to connect to MySQL: (1203) User howardkn already has more than 'max_user_connections' active connections
Warning: mysqli::query(): Couldn't fetch mysqli in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\index.php on line 66
Article <v931ri$4mni$3@dont-email.me>
Deutsch   English   Français   Italiano  
<v931ri$4mni$3@dont-email.me>

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

Path: ...!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 15:13:06 -0300
Organization: A noiseless patient Spider
Lines: 146
Message-ID: <v931ri$4mni$3@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> <v9316l$4msg$2@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 20:13:07 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="c24a25e0e0574963f5160c2b1c68553a";
	logging-data="154354"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1/v7V1lNVSCjgq/7VhylwN1BcXHcVTSvQU="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:HqQ7D4OsxB0UTDJoOuguhcFDAsI=
In-Reply-To: <v9316l$4msg$2@dont-email.me>
Content-Language: en-US
Bytes: 6206

On 08/08/2024 15:01, Bart wrote:
> On 08/08/2024 18: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.
> 
> In my C compiler I have no constexpr (don't know why you got that 
> impression). And I don't check that initialisers for integer types 
> overflow their destination.


It does not need to be "constexpr" just constant expressions like enum 
or case of switch. (Cast at compile time is not new in C23.)

> This is because within the language in general:
> 
>      char c; int i;
> 
>      c = i;
> 
> Such an assignment is not checked at runtime (and I don't know if this 
> can be warned against, or if a runtime check can be added).
> 
> This is just how C works: too-large values are silently truncated (there 
> are worse aspects of the language, like being able to do `int i; 
> (&i)[12345];`).

But this is something well defined, not UB (I guess).

> But you are presumably superimposing a new stricter language on top. In 
> the case, if my `c = i` assignment was not allowed, how do I get around 
> that; by a cast?
> 

I am just following C standard. Adding some extra warnings for wraparound.