Deutsch English Français Italiano |
<v93pfg$c7b8$1@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!3.eu.feeder.erje.net!2.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Bart <bc@freeuk.com> Newsgroups: comp.lang.c Subject: Re: how cast works? Date: Fri, 9 Aug 2024 01:56:15 +0100 Organization: A noiseless patient Spider Lines: 160 Message-ID: <v93pfg$c7b8$1@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> <v9310a$4v1a$2@dont-email.me> <v93565$6ffo$1@dont-email.me> <v93h12$9vom$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Fri, 09 Aug 2024 02:56:16 +0200 (CEST) Injection-Info: dont-email.me; posting-host="a5ef0e336b797e59eb82473df0f29c2d"; logging-data="400744"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19/gnT0KZBB5Z//1f116GUG" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:poG1JCTYCGjBAfxOjv5osTeA+/E= In-Reply-To: <v93h12$9vom$1@dont-email.me> Content-Language: en-GB Bytes: 6063 On 08/08/2024 23:32, David Brown wrote: > On 08/08/2024 21:09, Bart wrote: >> Sorry but my function is perfectly valid. It's taking a Bool value and >> converting it to an int. > > No, it is not. > > Attempting to use the value of a non-static local variable that has not > been initialised or assigned is undefined behaviour. Your function is > garbage. No one can draw any conclusions about how meaningless code is > compiled. FFS. You really think that makes a blind bit of difference? A variable is not initialised, so the bool->int code shown must be just random rubbish generated by the compiler? You think I wouldn't spot if there was something amiss? OK, let's initialise it and see what difference it actually makes. My code is now this: #include <stdbool.h> void BC(void) { _Bool b; int i; i=b; } void DB(void) { _Bool b=false; int i; i=b; } The output from gcc -O1 is this: BC: ret DB: ret There is no difference. So, even initialised, it tells me nothing about what might be involved in bool->int conversion. It is useless. Now I'll try it with -O0 (line breaks added): BC: push rbp mov rbp, rsp movzx eax, BYTE PTR [rbp-1] mov DWORD PTR [rbp-8], eax nop pop rbp ret DB: push rbp mov rbp, rsp mov BYTE PTR [rbp-1], 0 movzx eax, BYTE PTR [rbp-1] mov DWORD PTR [rbp-8], eax nop pop rbp ret Exactly the same code, except DB has an extra line to initialise that value. Are you surprised it is the same? I am 99% sure that you already knew this, but were pretending that the code was meaningless, for reasons that escape me. One more thing: the ASM code I posted earlier was from Clang 18.1, above it's from gcc 14.1. The Clang code masks bit 0 of the bool value; gcc doesn't. However, you can only know that by using -O0 in both cases. Using the -O1 or higher that you recommend, you only see this: BC: ret DB: ret for both compilers. That is utterly useless. YMMV. >> If you want to know what casting from bool to int entails, then >> testing it via a function call like this is the wrong way to do it, >> since half kj >> of it depends on what happens when evaluating arguments at the call site. >> > > Nope. So in: mov eax, ecx inside foo_b2i(), at what point did the 8-bit _Bool get turned into the 32-bit value in ecx? > That's fine for the nonsense function you wrote. Actually, MS (the poster) wrote those foo_* functions . >> >> >> The advantage of unoptimised code is that it will contain everything >> that is normally involved; it doesn't throw anything away. >> > > No, it does not - because normal code generated by C compilers used by C > programmers who want sensible results will be the result of compiling > with optimisation, and will look very different. As I said, this isn't production code of a real program. It is a single line. Elsewhere you had to resort to using statics (and linkage outside of a function) to stop code being eliminated out of existence. With -O0 you don't need such tricks, and don't need to think about what might have been removed that you really need to see. >> So, what's involved in turning Bool to int? According to your examples >> with -O1: nothing. You just copy 32 bits unchanged from one to the >> other. Mildly surprising, but you are of course right, right? >> > > Yes, I am right - and I don't see that as even mildly surprising here. > That's how you convert a _Bool in a register to an int in a register. We don't know where the bool passed to foo_b2i came from; maybe it was an element of an array or struct, so it would have been widened at some point before calling the function. So that example would give a misleading picture of what's involved. > > No. You are asking it to do something else - you are asking it to load > a _Bool from memory, not just convert it. It loads from memory and converts it in one instruction; isn't that something? But this is pretty much what your godbolt link does, where you have to resort to using static variables, since for -O1 and above, locals are kept in registers: movzx eax, BYTE PTR b[rip] It seems there /is/ something I overlooked: the -S output of gcc/clang is less readable, since variable names disappear: they either are kept in registers (where you don't know which is which); or they are addressed by numeric offsets, and again you don't know what is what.