Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Thiago Adams Newsgroups: comp.lang.c Subject: Re: how cast works? Date: Sun, 11 Aug 2024 14:16:00 -0300 Organization: A noiseless patient Spider Lines: 113 Message-ID: References: <87ttfu94yv.fsf@nosuchdomain.example.com> <87zfpj537h.fsf@nosuchdomain.example.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Sun, 11 Aug 2024 19:16:01 +0200 (CEST) Injection-Info: dont-email.me; posting-host="5178e0c40238d6cd6e3cb7269b7f3c31"; logging-data="2948527"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/Ec8YFjQYDWcFOCJe0hyLrsG/DUfTyNYg=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:QqYVe3ZsOdstb+zRQ3r9oQ2rMSU= In-Reply-To: Content-Language: en-GB Bytes: 4752 Em 8/11/2024 9:30 AM, Bart escreveu: > On 11/08/2024 13:23, Thiago Adams wrote: >> Em 8/10/2024 9:10 PM, Keith Thompson escreveu: >>> Thiago Adams writes: >>>> Em 8/10/2024 1:14 PM, Bart escreveu: >>>>>> >>>>>> Bart, Does your compiler support the `bool` type, where the value >>>>>> is always either 1 or 0? >>>>> There is a bool type, but it is treated like unsigned char, so is >>>>> non-conforming. >>>> >>>> I do the same in my compiler , when I transpile from C99 to C89. >>>> I was thinking how to make it conforming. >>>> For instance on each write. >>>> >>>> bool b = 123; -> unsigned char b = !!(123); >>>> >>>> The problem this does not fix unions, writing on int and reading >>>> from char. >>> >>> I don't think you need to fix that. >> >> [....] >> >>> Summary: >>> >>> Conversion from any scalar type to _Bool is well defined, and must yield >>> 0 or 1. >> >> >> I will fix in terns of expressions types. >> >>   - In this case cast to bool >>   - Assignment to bool >> >>> It's possible to force a representation other than 0 or 1 into a _Bool >>> object, bypassing any value conversion. >>> >>> Conversion from _Bool to any scalar type is well defined if the >>> operand is a _Bool object holding a representation of 0 or 1. >>> >>> Conversion from _Bool to any scalar type for an object holding some >>> representation other than 0 or 1 either yields 0 or 1 (depending >>> on the low-order bit) or has undefined behavior. >> >> I did a sample now.. >> >> #include >> >> int main() { >>      union { >>          int i; >>          _Bool b; >>      } data; >>      data.i = 123; >>      printf("%d", data.b); >> } >> >> it printed 123 not 1. >> So I think the assignment and cast covers all/most cases. >> (From some previous tests I thought this was printing 1) > > That's little different from this example: > >  #include > >  int main() { >      union { >          int i; >          float b; >      } data; >      data.i = 123; >      printf("%e", data.b); >  } > > I get some arbitrary float value printed. You're supposed to know what > you are doing with unions. One of my tests led me to the wrong conclusion that reading a boolean value would cause the compiler to add a conversion on read. I did something wrong..I don't remember. I will try to keep all tests next time. But now, everything is back to normal. union { int i; _Bool b; } data; data.b = 123; printf("%d", data.b); //prints 1 as expected union { int i; _Bool b; } data; data.i = 123; printf("%d", data.b); //prints 123 as expected > It's not something I'd worry about. If you're trying to make a safer C, > then you'd have to ban unions, or ban bools inside unions that could be > read out as a different type, or introduce tagged unions so that runtime > checking can be done. Something that could be done is to check in local context the last write type is the same of last read. Then we can have a warning if they are different.