Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #387379 > unrolled thread

how cast works?

Started byThiago Adams <thiago.adams@gmail.com>
First post2024-08-07 08:28 -0300
Last post2024-08-07 23:03 +0000
Articles 20 on this page of 121 — 14 participants

Back to article view | Back to comp.lang.c


Contents

  how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-07 08:28 -0300
    Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-07 08:33 -0300
      Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-07 13:13 -0700
      Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-11 17:43 -0700
        Re: how cast works? Vir Campestris <vir.campestris@invalid.invalid> - 2024-08-12 11:51 +0100
          Challenge/exercise problem - signum() function Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-12 08:17 -0700
            Re: Challenge/exercise problem - signum() function Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2024-08-12 16:07 +0000
              Re: Challenge/exercise problem - signum() function Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-12 09:57 -0700
    Re: how cast works? Dan Purgert <dan@djph.net> - 2024-08-07 20:00 +0000
      Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-07 13:26 -0700
      Re: how cast works? Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-08-07 23:00 +0000
      Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-08 08:14 -0300
        Re: how cast works? Bart <bc@freeuk.com> - 2024-08-08 14:23 +0100
          Re: how cast works? Michael S <already5chosen@yahoo.com> - 2024-08-08 19:32 +0300
            Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-08 14:11 -0300
            Re: how cast works? Bart <bc@freeuk.com> - 2024-08-08 18:29 +0100
              Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-08 14:50 -0300
                Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-08 14:57 -0300
                Re: how cast works? Bart <bc@freeuk.com> - 2024-08-08 19:01 +0100
                  Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-08 15:13 -0300
                Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-08 12:29 -0700
              Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-08 19:58 +0200
                Re: how cast works? Bart <bc@freeuk.com> - 2024-08-08 20:09 +0100
                  Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-09 00:32 +0200
                    Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-08 16:14 -0700
                      Re: how cast works? Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-08-09 02:47 +0000
                        Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-08 22:55 -0700
                        Re: how cast works? James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-09 02:08 -0400
                      Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-09 18:16 +0200
                        Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 12:18 -0700
                          Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-11 17:07 -0700
                            Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-11 20:14 -0700
                              Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-09-03 06:02 -0700
                    Re: how cast works? Bart <bc@freeuk.com> - 2024-08-09 01:56 +0100
                      Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-09 19:08 +0200
                        Re: how cast works? Bart <bc@freeuk.com> - 2024-08-10 11:03 +0100
                  Re: how cast works? Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-08-09 02:45 +0000
        Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-08 12:42 -0700
          Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-08 17:34 -0300
            Re: how cast works? Bart <bc@freeuk.com> - 2024-08-08 22:41 +0100
              Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-08 16:17 -0700
                Re: how cast works? Bart <bc@freeuk.com> - 2024-08-09 11:04 +0100
                  Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-09 19:12 +0200
                    Re: how cast works? Bart <bc@freeuk.com> - 2024-08-12 15:36 +0100
                  Re: how cast works? James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-09 13:57 -0400
                    Re: how cast works? Bart <bc@freeuk.com> - 2024-08-09 21:59 +0100
                      Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 14:47 -0700
                        Re: how cast works? Bart <bc@freeuk.com> - 2024-08-10 00:32 +0100
                          Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 17:12 -0700
                      Re: how cast works? James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-09 18:29 -0400
                        Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-13 11:18 +0200
                        Re: how cast works? Bart <bc@freeuk.com> - 2024-08-13 11:34 +0100
                        Re: how cast works? James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-13 07:51 -0400
                          Re: how cast works? Bart <bc@freeuk.com> - 2024-08-13 14:01 +0100
                            Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-13 12:46 -0700
                              Re: how cast works? Bart <bc@freeuk.com> - 2024-08-13 21:51 +0100
                                Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-13 16:46 -0700
                                  Re: how cast works? Bart <bc@freeuk.com> - 2024-08-14 00:56 +0100
                                    Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-18 03:37 -0700
                    Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 14:29 -0700
                      Re: how cast works? James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-09 18:35 -0400
                    Re: how cast works? Kaz Kylheku <643-408-1753@kylheku.com> - 2024-08-09 21:30 +0000
                      Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 14:57 -0700
                        Re: how cast works? Kaz Kylheku <643-408-1753@kylheku.com> - 2024-08-09 23:14 +0000
                          Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 16:58 -0700
                            Re: how cast works? Kaz Kylheku <643-408-1753@kylheku.com> - 2024-08-10 00:06 +0000
                              Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 17:27 -0700
                              Re: how cast works? James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-09 20:31 -0400
                            Re: how cast works? Bart <bc@freeuk.com> - 2024-08-10 01:11 +0100
                              Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-13 11:23 +0200
                          Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-11 17:32 -0700
                      Re: how cast works? James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-09 18:35 -0400
                      Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-11 17:27 -0700
                  Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 12:23 -0700
                    Re: how cast works? Bart <bc@freeuk.com> - 2024-08-09 21:31 +0100
                      Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 13:49 -0700
                        Re: how cast works? Bart <bc@freeuk.com> - 2024-08-09 22:01 +0100
                  Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-12 00:33 -0700
                    Re: how cast works? Bart <bc@freeuk.com> - 2024-08-12 12:21 +0100
                Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-11 17:46 -0700
                  Re: how cast works? Bart <bc@freeuk.com> - 2024-08-12 02:00 +0100
                    Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-11 20:23 -0700
                    Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-11 20:37 -0700
                      Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-11 21:33 -0700
                        Re: how cast works? Ben Bacarisse <ben@bsb.me.uk> - 2024-08-12 16:57 +0100
                          Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-12 10:04 -0700
                            Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-12 13:35 -0700
              Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-09 07:57 -0300
                Re: how cast works? Bart <bc@freeuk.com> - 2024-08-09 16:25 +0100
                  Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 12:06 -0700
                Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-09 19:20 +0200
                  Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-09 15:54 -0300
                    Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-09 16:05 -0300
                      Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-09 21:43 +0200
                      Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 13:28 -0700
                    Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-09 22:01 +0200
                      Re: how cast works? Bart <bc@freeuk.com> - 2024-08-10 11:17 +0100
                        Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-10 10:15 -0300
                          Re: how cast works? Bart <bc@freeuk.com> - 2024-08-10 17:14 +0100
                            Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-10 20:01 -0300
                              Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-10 17:10 -0700
                                Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-11 09:23 -0300
                                  Re: how cast works? Bart <bc@freeuk.com> - 2024-08-11 13:30 +0100
                                    Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-11 14:16 -0300
                                  Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-11 13:38 -0700
                                    Re: how cast works? Bart <bc@freeuk.com> - 2024-08-12 12:24 +0100
                    Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 13:26 -0700
                      Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-09 18:01 -0300
                        Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 14:53 -0700
                Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-09 12:03 -0700
                  Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-09 16:22 -0300
            Re: how cast works? David Brown <david.brown@hesbynett.no> - 2024-08-09 00:36 +0200
      Re: how cast works? Dan Purgert <dan@djph.net> - 2024-08-08 14:08 +0000
      Re: how cast works? Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-08-09 02:42 +0000
    Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-07 13:08 -0700
      Re: how cast works? Thiago Adams <thiago.adams@gmail.com> - 2024-08-08 08:35 -0300
        Re: how cast works? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-08-08 12:39 -0700
        Re: how cast works? James Kuyper <jameskuyper@alumni.caltech.edu> - 2024-08-08 18:40 -0400
          Re: how cast works? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-08-11 17:15 -0700
      Is there an audio book version (Was: how cast works?) gazelle@shell.xmission.com (Kenny McCormack) - 2024-08-08 16:19 +0000
    Re: how cast works? Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-08-07 23:03 +0000

Page 6 of 7 — ← Prev page 1 2 3 4 5 [6] 7  Next page →


#387475

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-08-10 17:10 -0700
Message-ID<87zfpj537h.fsf@nosuchdomain.example.com>
In reply to#387474
Thiago Adams <thiago.adams@gmail.com> 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.

In the following, I'll refer to _Bool.  The same type is also called
bool if you have `#include <stdbool.h>` *or* if you have a C23 compiler.

It's always going to be possible to use type punning (memcpy, pointer
casting, union) to force a representation other than 00000000 or
00000001 into a _Bool object.

The standard doesn't have a rule that says a _Bool object can only have
the value 0 or 1.  It says that *conversion* to _Bool yields a result of
0 or 1.  And yes, you have to deal with that if you're translating C99
or later to C90, for both explicit and implicit conversions.

Suppose you do something like this:

    _Bool b;
    *(unsigned char*)&b = 0xff; // assume sizeof (_Bool) == 1
    int i = b;

What is the value of b?

Under C23 rules, _Bool has 1 value bit and N-1 (typically 7) padding
bits.  Any non-zero padding bits *either* create a trap representation
(C23 calls it a non-value representation) *or* are ignored when
determining the value of the object.

(_Bool can have either 254 trap representations or none.  It's possible
that it might have some different number of trap representations, but
that's unlikely.)

If 11111111 is a trap/non-value representation, the behavior of
`int i = b;` is undefined; setting i to 255 or -1 are two of many
possible behaviors.  If the padding bits are ignored, it must set i to 1.

Experiment shows that gcc sets i to 255 (implying that it's a trap
representation) while clang sets i to 1 (which could imply that it's not
a trap representation, but that's still a possible result of UB).

Summary:

Conversion from any scalar type to _Bool is well defined, and must yield
0 or 1.

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.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#387476

FromThiago Adams <thiago.adams@gmail.com>
Date2024-08-11 09:23 -0300
Message-ID<v9aafn$298lv$1@dont-email.me>
In reply to#387475
Em 8/10/2024 9:10 PM, Keith Thompson escreveu:
> Thiago Adams <thiago.adams@gmail.com> 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 <stdio.h>

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)

The motivation for C89 in cake was not to support old compilers, but 
generate code that is compatible with C++98. In this aspect bool was 
already there in C++98.(This just gave me idea to add target c++98)




[toc] | [prev] | [next] | [standalone]


#387477

FromBart <bc@freeuk.com>
Date2024-08-11 13:30 +0100
Message-ID<v9aasg$2mfsi$1@dont-email.me>
In reply to#387476
On 11/08/2024 13:23, Thiago Adams wrote:
> Em 8/10/2024 9:10 PM, Keith Thompson escreveu:
>> Thiago Adams <thiago.adams@gmail.com> 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 <stdio.h>
> 
> 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 <stdio.h>

  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.

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.


[toc] | [prev] | [next] | [standalone]


#387478

FromThiago Adams <thiago.adams@gmail.com>
Date2024-08-11 14:16 -0300
Message-ID<v9arkh$2pvdf$1@dont-email.me>
In reply to#387477
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 <thiago.adams@gmail.com> 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 <stdio.h>
>>
>> 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 <stdio.h>
> 
>   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.


[toc] | [prev] | [next] | [standalone]


#387483

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-08-11 13:38 -0700
Message-ID<87bk1yg5hc.fsf@nosuchdomain.example.com>
In reply to#387476
Thiago Adams <thiago.adams@gmail.com> writes:
> Em 8/10/2024 9:10 PM, Keith Thompson escreveu:
>> Thiago Adams <thiago.adams@gmail.com> 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

You need to cover all cases where a scalar value is converted to _Bool.
That includes (explicit) casts, assignment, initialization, argument
passing, and returning from a _Bool function.

Ideally you'd have one place in your code that handles conversions, but
you'll want to test all those cases and more.

>> 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 <stdio.h>
>
> int main() {
>     union {
>         int i;
>         _Bool b;
>     } data;
>     data.i = 123;
>     printf("%d", data.b);
> }
>
> it printed 123 not 1.

I get 123 if I compile with gcc, 1 if I compile with clang.
Both results are valid.

> So I think the assignment and cast covers all/most cases.
> (From some previous tests I thought this was printing 1)
>
> The motivation for C89 in cake was not to support old compilers, but
> generate code that is compatible with C++98. In this aspect bool was
> already there in C++98.(This just gave me idea to add target c++98)

C++ may have different rules, which you can discuss in comp.lang.c++.

>
>
>
>
>

A lot of your articles have multiple blank lines at the end.  Can you
try to avoid that?

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#387512

FromBart <bc@freeuk.com>
Date2024-08-12 12:24 +0100
Message-ID<v9cre7$38lqf$2@dont-email.me>
In reply to#387483
On 11/08/2024 21:38, Keith Thompson wrote:
> Thiago Adams <thiago.adams@gmail.com> writes:

>>   - In this case cast to bool
>>   - Assignment to bool
> 
> You need to cover all cases where a scalar value is converted to _Bool.
> That includes (explicit) casts,

Is there any other kind?

[toc] | [prev] | [next] | [standalone]


#387444

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-08-09 13:26 -0700
Message-ID<87ikw9788w.fsf@nosuchdomain.example.com>
In reply to#387433
Thiago Adams <thiago.adams@gmail.com> writes:
> Em 8/9/2024 2:20 PM, David Brown escreveu:
>> On 09/08/2024 12:57, Thiago Adams wrote:
>>> Em 8/8/2024 6:41 PM, Bart escreveu:
>>>> On 08/08/2024 21:34, Thiago Adams wrote:
>>>>> On 08/08/2024 16:42, Keith Thompson wrote:
>>>>>> Thiago Adams <thiago.adams@gmail.com> writes:
>>>>>>> On 07/08/2024 17:00, Dan Purgert wrote:
>>>>>>>> On 2024-08-07, Thiago Adams wrote:
>>>>>> [...]
>>>>>>>>> How about floating point?
>>>>>>>> Floating point is a huge mess, and has a few variations for
>>>>>>>> encoding;
>>>>>>>> though I think most C implementations use the one from the
>>>>>>>> IEEE on 1985
>>>>>>>> (uh, IEEE754, I think?)
>>>>>>>
>>>>>>> I didn't specify properly , but my question was more about floating
>>>>>>> point registers. I think in this case they have specialized
>>>>>>> registers.
>>>>>>
>>>>>> Who is "they"?
>>>>>>
>>>>>> Some CPUs have floating-point registers, some don't.  C says nothing
>>>>>> about registers.
>>>>>>
>>>>>> What exactly is your question?  Is it not already answered by reading
>>>>>> the "Conversions" section of the C standard?
>>>>>>
>>>>>
>>>>>
>>>>> This part is related with the previous question about the origins
>>>>> of integer promotions.
>>>>>
>>>>> We don't have "char" register or signed/unsigned register. But I
>>>>> believe we may have double and float registers. So float does not
>>>>> need to be converted to double.
>>>>>
>>>>> There is no specif question here, just trying to understand the
>>>>> rationally behind the conversions rules.
>>>>
>>>> The rules have little to do with concrete machines with registers.
>>>>
>>>> Your initial post showed come confusion about how conversions
>>>> work. They are not performed 'in-place', any more than writing `a
>>>> + 1` changes the value of `a`.
>>>>
>>>> Take:
>>>>
>>>>      int a; double x;
>>>>
>>>>      x = (double)a;
>>>>
>>>> The cast is implicit here but I've written it out to make it
>>>> clear. My C compiler produces intermediate code like this before
>>>> converting it to native code:
>>>>
>>>>      push x   r64                   # r64 means float64
>>>>      fix      r64 -> i32
>>>>      pop  a   i32
>>>>
>>>> I could choose to interprete this code just as it is. Then, in
>>>> this execution model, there are no registers at all, only a stack
>>>> that can hold data of any type.
>>>>
>>>> The 'fix' instruction pops the double value from the stack,
>>>> converts it to int (which involves changing both the bit-pattern,
>>>> and the bit-width), and pushes it back onto the stack.
>>>>
>>>> Registers come into it when running it directly on a real
>>>> machine. But you seem more concerned with safety and correctness
>>>> than performance, so there's probably no real need to look at
>>>> actual generated native code.
>>>>
>>>> That'll just be confusing (especially if you follow the advice to
>>>> generate only optimised code).
>>>>
>>>>
>>>>
>>>>
>>> This part was always clear to me:
>>>
>>> "They  are not performed 'in-place', any more than writing `a + 1`
>>> changes the value of `a`."
>>>
>>> Lets take double to int.
>>>
>>> In this case the bits of double needs to be reinterpreted (copied
>>> to) int.
>>>
>>> So the answer "how it works" can be
>>>
>>> always/generally machine has a instruction to do this
>>>
>>> or.. this is defined by the IIE ... standard as ...
>>>
>>>
>> It would be helpful if you made more of an effort to write clearly
>> here.   (We know you can do so when you want to.)  It is very
>> difficult to follow what you are referring to here - what is "this
>> case" here?  A conversion from a double to an int certainly does not
>> re-interpret or copy bits - like other conversions, it copies the
>> /value/ to the best possible extent given the limitations of the
>> types.
>
> Everything is a bit mixed up, but I'll try to explain the part about
> registers that I have in mind.

Why you keep talking about registers?  The C standard does not talk
about registers, and the promotion rules are based on which *operations*
are available, not what kinds of registers a given CPU happens to have.

> In C, when you have an expression like char + char, each char is
> promoted to int. The computation then occurs as int + int.

Right.  And the most important thing to keep in mind is that it works
that way *because the C standard says so*.

If you're looking for a rationale for this, it's probably because some
early C compilers were for target systems that didn't provide operations
on narrow types.  (The PDP-11 does have instructions that operate on
8-bit bytes, but the arithmetic instructions operate only on 16-bit
words.)  But the C standard rules apply to all conforming C
implementations.  If a target CPU happens to provide a 1-byte add
instruction, a C compiler can't use it unless it can prove that the
result is consistent with C semantics.

Knowing why the C standard says what it says can be interesting, but
it's not necessarily directly useful.

> On the other hand, when you have float + float, it remains as float + float.

That's implementation-defined.  Read the "Characteristics of floating
types <float.h>" section of the C standard (it's 5.2.5.3.3 in the N3220
draft) and look for FLT_EVAL_METHOD.  If FLT_EVAL_METHOD (defined in
<float.h>) is 0, float operations are done in type float.  If it's 1,
float operations are done in type double.  If it's 2, all floating-point
operations are done in type long double.

> My guess for this design is that computations involving char are done
> using registers that are the size of an int.

Who says the target CPU even has registers, or that computations can't
be done directly on values in memory?

> But, float + float is not promoted to double, so I assume that the
> computer has specific float registers or similar operation
> instructions for float.

Again, some CPUs have floating-point registers and some do not.  Those
that don't might store floating-point values in the same registers used
for integer values, applying different instructions to operate on them.
Of those that do have floating-point registers, some have registers that
can hold a double value (typically 64 bits); they may or may not be able
to treat a half-register as a 32-bot float value.

The rules in the C standard are, for the most part, based on the
capabilities of CPUs that existed when the standard was written, not
necessarily on modern CPUs (though there have been tweaks in later
editions).

> Regarding the part about signed/unsigned registers and operations, I
> must admit that I'm not sure. I was planning to check on Compiler
> Explorer, but I haven't done that yet.
>
> I can frame the question like this: Does the computer make a
> distinction when adding signed versus unsigned integers? Are there
> specific assembly instructions for signed versus unsigned operations,
> covering all possible combinations?

Maybe.

What is your goal here?  Are you trying to understand the history behind
the rules given in the C standard, or trying to understand the rules
themselves, or both?

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#387449

FromThiago Adams <thiago.adams@gmail.com>
Date2024-08-09 18:01 -0300
Message-ID<v9602l$60n0$1@dont-email.me>
In reply to#387444
Em 8/9/2024 5:26 PM, Keith Thompson escreveu:
> Thiago Adams <thiago.adams@gmail.com> writes:
>> Em 8/9/2024 2:20 PM, David Brown escreveu:
>>> On 09/08/2024 12:57, Thiago Adams wrote:
>>>> Em 8/8/2024 6:41 PM, Bart escreveu:
>>>>> On 08/08/2024 21:34, Thiago Adams wrote:
>>>>>> On 08/08/2024 16:42, Keith Thompson wrote:
>>>>>>> Thiago Adams <thiago.adams@gmail.com> writes:
>>>>>>>> On 07/08/2024 17:00, Dan Purgert wrote:
>>>>>>>>> On 2024-08-07, Thiago Adams wrote:
>>>>>>> [...]
>>>>>>>>>> How about floating point?
>>>>>>>>> Floating point is a huge mess, and has a few variations for
>>>>>>>>> encoding;
>>>>>>>>> though I think most C implementations use the one from the
>>>>>>>>> IEEE on 1985
>>>>>>>>> (uh, IEEE754, I think?)
>>>>>>>>
>>>>>>>> I didn't specify properly , but my question was more about floating
>>>>>>>> point registers. I think in this case they have specialized
>>>>>>>> registers.
>>>>>>>
>>>>>>> Who is "they"?
>>>>>>>
>>>>>>> Some CPUs have floating-point registers, some don't.  C says nothing
>>>>>>> about registers.
>>>>>>>
>>>>>>> What exactly is your question?  Is it not already answered by reading
>>>>>>> the "Conversions" section of the C standard?
>>>>>>>
>>>>>>
>>>>>>
>>>>>> This part is related with the previous question about the origins
>>>>>> of integer promotions.
>>>>>>
>>>>>> We don't have "char" register or signed/unsigned register. But I
>>>>>> believe we may have double and float registers. So float does not
>>>>>> need to be converted to double.
>>>>>>
>>>>>> There is no specif question here, just trying to understand the
>>>>>> rationally behind the conversions rules.
>>>>>
>>>>> The rules have little to do with concrete machines with registers.
>>>>>
>>>>> Your initial post showed come confusion about how conversions
>>>>> work. They are not performed 'in-place', any more than writing `a
>>>>> + 1` changes the value of `a`.
>>>>>
>>>>> Take:
>>>>>
>>>>>       int a; double x;
>>>>>
>>>>>       x = (double)a;
>>>>>
>>>>> The cast is implicit here but I've written it out to make it
>>>>> clear. My C compiler produces intermediate code like this before
>>>>> converting it to native code:
>>>>>
>>>>>       push x   r64                   # r64 means float64
>>>>>       fix      r64 -> i32
>>>>>       pop  a   i32
>>>>>
>>>>> I could choose to interprete this code just as it is. Then, in
>>>>> this execution model, there are no registers at all, only a stack
>>>>> that can hold data of any type.
>>>>>
>>>>> The 'fix' instruction pops the double value from the stack,
>>>>> converts it to int (which involves changing both the bit-pattern,
>>>>> and the bit-width), and pushes it back onto the stack.
>>>>>
>>>>> Registers come into it when running it directly on a real
>>>>> machine. But you seem more concerned with safety and correctness
>>>>> than performance, so there's probably no real need to look at
>>>>> actual generated native code.
>>>>>
>>>>> That'll just be confusing (especially if you follow the advice to
>>>>> generate only optimised code).
>>>>>
>>>>>
>>>>>
>>>>>
>>>> This part was always clear to me:
>>>>
>>>> "They  are not performed 'in-place', any more than writing `a + 1`
>>>> changes the value of `a`."
>>>>
>>>> Lets take double to int.
>>>>
>>>> In this case the bits of double needs to be reinterpreted (copied
>>>> to) int.
>>>>
>>>> So the answer "how it works" can be
>>>>
>>>> always/generally machine has a instruction to do this
>>>>
>>>> or.. this is defined by the IIE ... standard as ...
>>>>
>>>>
>>> It would be helpful if you made more of an effort to write clearly
>>> here.   (We know you can do so when you want to.)  It is very
>>> difficult to follow what you are referring to here - what is "this
>>> case" here?  A conversion from a double to an int certainly does not
>>> re-interpret or copy bits - like other conversions, it copies the
>>> /value/ to the best possible extent given the limitations of the
>>> types.
>>
>> Everything is a bit mixed up, but I'll try to explain the part about
>> registers that I have in mind.
> 
> Why you keep talking about registers?  The C standard does not talk
> about registers, and the promotion rules are based on which *operations*
> are available, not what kinds of registers a given CPU happens to have.
> 

I use "register" to talk about how hardware works.

>> In C, when you have an expression like char + char, each char is
>> promoted to int. The computation then occurs as int + int.
> 
> Right.  And the most important thing to keep in mind is that it works
> that way *because the C standard says so*.
> 
> If you're looking for a rationale for this, it's probably because some
> early C compilers were for target systems that didn't provide operations
> on narrow types.  (The PDP-11 does have instructions that operate on
> 8-bit bytes, but the arithmetic instructions operate only on 16-bit
> words.)  But the C standard rules apply to all conforming C
> implementations.  If a target CPU happens to provide a 1-byte add
> instruction, a C compiler can't use it unless it can prove that the
> result is consistent with C semantics.
> 
> Knowing why the C standard says what it says can be interesting, but
> it's not necessarily directly useful.
> 
>> On the other hand, when you have float + float, it remains as float + float.
> 
> That's implementation-defined.  Read the "Characteristics of floating
> types <float.h>" section of the C standard (it's 5.2.5.3.3 in the N3220
> draft) and look for FLT_EVAL_METHOD.  If FLT_EVAL_METHOD (defined in
> <float.h>) is 0, float operations are done in type float.  If it's 1,
> float operations are done in type double.  If it's 2, all floating-point
> operations are done in type long double.
> 
>> My guess for this design is that computations involving char are done
>> using registers that are the size of an int.
> 
> Who says the target CPU even has registers, or that computations can't
> be done directly on values in memory?
> 
>> But, float + float is not promoted to double, so I assume that the
>> computer has specific float registers or similar operation
>> instructions for float.
> 
> Again, some CPUs have floating-point registers and some do not.  Those
> that don't might store floating-point values in the same registers used
> for integer values, applying different instructions to operate on them.
> Of those that do have floating-point registers, some have registers that
> can hold a double value (typically 64 bits); they may or may not be able
> to treat a half-register as a 32-bot float value.
> 
> The rules in the C standard are, for the most part, based on the
> capabilities of CPUs that existed when the standard was written, not
> necessarily on modern CPUs (though there have been tweaks in later
> editions).
> 
>> Regarding the part about signed/unsigned registers and operations, I
>> must admit that I'm not sure. I was planning to check on Compiler
>> Explorer, but I haven't done that yet.
>>
>> I can frame the question like this: Does the computer make a
>> distinction when adding signed versus unsigned integers? Are there
>> specific assembly instructions for signed versus unsigned operations,
>> covering all possible combinations?
> 
> Maybe.
> 
> What is your goal here?  Are you trying to understand the history behind
> the rules given in the C standard, or trying to understand the rules
> themselves, or both?
> 

both.

I have fixed cake constant expressions that were not doing integer 
promotion correctly. So I implemented the conversion rules.(6.3.1.8 
Usual arithmetic conversions)

To implement the constant expression for instance (char)1234 I had to 
implement the cast rule "as script"  creating the combinations of all 
types x types.

I was trying to implement some cast without all combinations type x type 
then I started the topic to understand how cast works to try to emulate 
what hardware does using bits..but at the end I did all combinations 
then the C compiler that compiles by C compiler will do what is necessary.

In the future I also planning creating a backend so I want to understand 
better the low level.
Apart of that I like to understand how/why things works.







[toc] | [prev] | [next] | [standalone]


#387454

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-08-09 14:53 -0700
Message-ID<87r0ax5poi.fsf@nosuchdomain.example.com>
In reply to#387449
Thiago Adams <thiago.adams@gmail.com> writes:
> Em 8/9/2024 5:26 PM, Keith Thompson escreveu:
>> Thiago Adams <thiago.adams@gmail.com> writes:
>>> Em 8/9/2024 2:20 PM, David Brown escreveu:
>>>> On 09/08/2024 12:57, Thiago Adams wrote:
>>>>> Em 8/8/2024 6:41 PM, Bart escreveu:
>>>>>> On 08/08/2024 21:34, Thiago Adams wrote:
>>>>>>> On 08/08/2024 16:42, Keith Thompson wrote:
>>>>>>>> Thiago Adams <thiago.adams@gmail.com> writes:
>>>>>>>>> On 07/08/2024 17:00, Dan Purgert wrote:
>>>>>>>>>> On 2024-08-07, Thiago Adams wrote:
>>>>>>>> [...]
>>>>>>>>>>> How about floating point?
>>>>>>>>>> Floating point is a huge mess, and has a few variations for
>>>>>>>>>> encoding;
>>>>>>>>>> though I think most C implementations use the one from the
>>>>>>>>>> IEEE on 1985
>>>>>>>>>> (uh, IEEE754, I think?)
>>>>>>>>>
>>>>>>>>> I didn't specify properly , but my question was more about floating
>>>>>>>>> point registers. I think in this case they have specialized
>>>>>>>>> registers.
>>>>>>>>
>>>>>>>> Who is "they"?
>>>>>>>>
>>>>>>>> Some CPUs have floating-point registers, some don't.  C says nothing
>>>>>>>> about registers.
>>>>>>>>
>>>>>>>> What exactly is your question?  Is it not already answered by reading
>>>>>>>> the "Conversions" section of the C standard?
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> This part is related with the previous question about the origins
>>>>>>> of integer promotions.
>>>>>>>
>>>>>>> We don't have "char" register or signed/unsigned register. But I
>>>>>>> believe we may have double and float registers. So float does not
>>>>>>> need to be converted to double.
>>>>>>>
>>>>>>> There is no specif question here, just trying to understand the
>>>>>>> rationally behind the conversions rules.
>>>>>>
>>>>>> The rules have little to do with concrete machines with registers.
>>>>>>
>>>>>> Your initial post showed come confusion about how conversions
>>>>>> work. They are not performed 'in-place', any more than writing `a
>>>>>> + 1` changes the value of `a`.
>>>>>>
>>>>>> Take:
>>>>>>
>>>>>>       int a; double x;
>>>>>>
>>>>>>       x = (double)a;
>>>>>>
>>>>>> The cast is implicit here but I've written it out to make it
>>>>>> clear. My C compiler produces intermediate code like this before
>>>>>> converting it to native code:
>>>>>>
>>>>>>       push x   r64                   # r64 means float64
>>>>>>       fix      r64 -> i32
>>>>>>       pop  a   i32
>>>>>>
>>>>>> I could choose to interprete this code just as it is. Then, in
>>>>>> this execution model, there are no registers at all, only a stack
>>>>>> that can hold data of any type.
>>>>>>
>>>>>> The 'fix' instruction pops the double value from the stack,
>>>>>> converts it to int (which involves changing both the bit-pattern,
>>>>>> and the bit-width), and pushes it back onto the stack.
>>>>>>
>>>>>> Registers come into it when running it directly on a real
>>>>>> machine. But you seem more concerned with safety and correctness
>>>>>> than performance, so there's probably no real need to look at
>>>>>> actual generated native code.
>>>>>>
>>>>>> That'll just be confusing (especially if you follow the advice to
>>>>>> generate only optimised code).
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>> This part was always clear to me:
>>>>>
>>>>> "They  are not performed 'in-place', any more than writing `a + 1`
>>>>> changes the value of `a`."
>>>>>
>>>>> Lets take double to int.
>>>>>
>>>>> In this case the bits of double needs to be reinterpreted (copied
>>>>> to) int.
>>>>>
>>>>> So the answer "how it works" can be
>>>>>
>>>>> always/generally machine has a instruction to do this
>>>>>
>>>>> or.. this is defined by the IIE ... standard as ...
>>>>>
>>>>>
>>>> It would be helpful if you made more of an effort to write clearly
>>>> here.   (We know you can do so when you want to.)  It is very
>>>> difficult to follow what you are referring to here - what is "this
>>>> case" here?  A conversion from a double to an int certainly does not
>>>> re-interpret or copy bits - like other conversions, it copies the
>>>> /value/ to the best possible extent given the limitations of the
>>>> types.
>>>
>>> Everything is a bit mixed up, but I'll try to explain the part about
>>> registers that I have in mind.
>> Why you keep talking about registers?  The C standard does not talk
>> about registers, and the promotion rules are based on which *operations*
>> are available, not what kinds of registers a given CPU happens to have.
>
> I use "register" to talk about how hardware works.

I don't see how that makes sense.  Not all CPUs have registers.  For
CPUs that do have registers, some support operations directly on memory.
Register size does not constrain the set of operations that are
available; for example a CPU might have 64-bit registers and support
both 64-bit and 32-bit operations.

Registers are largely irrelevant.

[...]

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#387434

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-08-09 12:03 -0700
Message-ID<8734nd8qn7.fsf@nosuchdomain.example.com>
In reply to#387423
Thiago Adams <thiago.adams@gmail.com> writes:
[...]
> This part was always clear to me:
>
> "They  are not performed 'in-place', any more than writing `a + 1`
> changes the value of `a`."
>
> Lets take double to int.
>
> In this case the bits of double needs to be reinterpreted (copied to) int.

The word "reinterpreted" usually refers to taking a given representation
(sequence of bits) and treating it as a value of a specified type
*without changing the bits*.  (<OT>C++ even has "reintrepret_cast" as a
keyword.</OT>)

Converting from int to double does not reinterpret the bits.  It creates
a new value that is mathematically equal (or nearly so) to the operand
value.

> So the answer "how it works" can be
>
> always/generally machine has a instruction to do this
>
> or.. this is defined by the IIE ... standard as ...

Do you mean the IEEE standard?  As always, the C standard defines the
semantics of conversions.  For an implementation that claims to conform
to IEEE floating-point standard (ISO/IEC 60559), the semantics are
specified more precisely.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#387439

FromThiago Adams <thiago.adams@gmail.com>
Date2024-08-09 16:22 -0300
Message-ID<v95q9m$2oa92$3@dont-email.me>
In reply to#387434
Em 8/9/2024 4:03 PM, Keith Thompson escreveu:
> Thiago Adams <thiago.adams@gmail.com> writes:
> [...]
>> This part was always clear to me:
>>
>> "They  are not performed 'in-place', any more than writing `a + 1`
>> changes the value of `a`."
>>
>> Lets take double to int.
>>
>> In this case the bits of double needs to be reinterpreted (copied to) int.
> 
> The word "reinterpreted" usually refers to taking a given representation
> (sequence of bits) and treating it as a value of a specified type
> *without changing the bits*.  (<OT>C++ even has "reintrepret_cast" as a
> keyword.</OT>)
> 
> Converting from int to double does not reinterpret the bits.  It creates
> a new value that is mathematically equal (or nearly so) to the operand
> value.
> 
>> So the answer "how it works" can be
>>
>> always/generally machine has a instruction to do this
>>
>> or.. this is defined by the IIE ... standard as ...
> 
> Do you mean the IEEE standard?  As always, the C standard defines the
> semantics of conversions.  For an implementation that claims to conform
> to IEEE floating-point standard (ISO/IEC 60559), the semantics are
> specified more precisely.
> 

Yes. maybe the conversion double to int for instance, is related with 
truncation, and this is specified on IEEE.
The inverse int to double is similar. For instance ULLONGMAX to double.

I guess all computers languages works in the same way today because also 
hardware works following the floating point standards.


--

We already have many topics in one...but I am adding one more. :D 
_Decimal32 , _Decimal64 etc..

C23 have these new types. I think it has to me emulated because it is 
not something implemented on hardware.

C started as being something more hardware related, but now we have 
complex types, bool, _Decimal.. I think all these types are "emulated".











[toc] | [prev] | [next] | [standalone]


#387412

FromDavid Brown <david.brown@hesbynett.no>
Date2024-08-09 00:36 +0200
Message-ID<v93ha8$9vom$2@dont-email.me>
In reply to#387409
On 08/08/2024 22:34, Thiago Adams wrote:
> On 08/08/2024 16:42, Keith Thompson wrote:
>> Thiago Adams <thiago.adams@gmail.com> writes:
>>> On 07/08/2024 17:00, Dan Purgert wrote:
>>>> On 2024-08-07, Thiago Adams wrote:
>> [...]
>>>>> How about floating point?
>>>> Floating point is a huge mess, and has a few variations for
>>>> encoding;
>>>> though I think most C implementations use the one from the IEEE on 1985
>>>> (uh, IEEE754, I think?)
>>>
>>> I didn't specify properly , but my question was more about floating
>>> point registers. I think in this case they have specialized registers.
>>
>> Who is "they"?
>>
>> Some CPUs have floating-point registers, some don't.  C says nothing
>> about registers.
>>
>> What exactly is your question?  Is it not already answered by reading
>> the "Conversions" section of the C standard?
>>
> 
> 
> This part is related with the previous question about the origins of 
> integer promotions.
> 
> We don't have "char" register or signed/unsigned register. But I believe 
> we may have double and float registers. So float does not need to be 
> converted to double.
> 
> There is no specif question here, just trying to understand the 
> rationally behind the conversions rules.
> 
> 

Stop trying to think about registers or implementations until you have 
understood the meaning of the conversions, as detailed in the C 
standards.  Implementation details are just that - implementation 
details, which vary from target to target, compiler to compiler, and 
according to the circumstances and the rest of the surrounding code.

In general, conversions try to preserve values (with the exceptions and 
limitations detailed in the standards).  If that involves changing the 
underlying bit representations, then those changes are made.  If no 
changes are needed, no changes will be made.

[toc] | [prev] | [next] | [standalone]


#387394

FromDan Purgert <dan@djph.net>
Date2024-08-08 14:08 +0000
Message-ID<slrnvb9kae.28a.dan@djph.net>
In reply to#387381
On 2024-08-08, Stefan Ram wrote:
> Dan Purgert <dan@djph.net> wrote or quoted:
>>I don't know what happens when you're changing datatype lengths, but if
>>they're the same length, it's just telling the compiler what the
>>variable should be treated as (e.g. [8-bit] int to char)
>
>   Casting doesn't tweak a value right where it sits, so you don't
>   have to stress about resizing memory. (It hands you an rvalue,
>   not an lvalue.) 

Yeah, I have to admit I've been driving myself mad trying to learn
AVR-Assembly lately, so ... types don't exist :|

-- 
|_|O|_| 
|_|_|O| Github: https://github.com/dpurgert
|O|O|O| PGP: DDAB 23FB 19FA 7D85 1CC1  E067 6D65 70E5 4CE7 2860

[toc] | [prev] | [next] | [standalone]


#387417

FromLawrence D'Oliveiro <ldo@nz.invalid>
Date2024-08-09 02:42 +0000
Message-ID<v93vne$hjg3$2@dont-email.me>
In reply to#387381
On 8 Aug 2024 12:44:46 GMT, Stefan Ram wrote:

>   The whole casting concept hails from Algol.

Type conversions are as old as the concept of types themselves.

Algol 68 introduced the term “coercion” for explicit type conversions.

[toc] | [prev] | [next] | [standalone]


#387382

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-08-07 13:08 -0700
Message-ID<87frrg9jud.fsf@nosuchdomain.example.com>
In reply to#387379
Thiago Adams <thiago.adams@gmail.com> writes:
> How cast works?
> Does it changes the memory?
> For instance, from "unsigned int" to "signed char".
> Is it just like discarding bytes or something else?

It depends on the source and target types.

A cast is an explicit conversion.  It takes a value of some type and
yields a value of some (other) type -- or of the same type.  The
semantics of a conversion are not affected by whether it's done
explicitly or implicitly.

The rules depend on the source and target types, and are specified in
the standard, section 6.3 "Conversions".  You'll need to read the whole
thing.

> For instance, any 4 bytes type, cast to 2 bytes type is just the lower
> 2 bytes?
>
> [A][B][C][D]
> ->
> [A][B]

For some combinations of type, a conversion *might* be implemented that
way.  Converting a 4-byte float to a 2-byte short definitely does not.

Conversions between pointer types, and between a pointer and an integer
of the same size, are *typically* implemented by copying or
reinterpreting the bits, but that's not universal.  An implementation
could have different representations, even different sizes, for pointers
of different types.

> I also would like to understand better signed and unsigned.
> There is no such think as "signed" or "unsigned" register, right?
> How about floating point?

The C standard has no concept of registers (the "register" keyword
notwithstanding).  All conversions are defined in terms of values.
(Some CPUs have distinct floating-point registers, but that affect
the semantics of floating-point operations.)  An implementation will use
registers and operations on them to implement the semantics defined in
the standard (assuming the target CPU has registers).

> The motivation problem.
> I have a union, with unsigned int, unsigned char etc.(all types)
> I need to execute a cast in runtime (like script).
> The problem is that this causes an explosion of combinations that I am
> trying to avoid.

I don't think you're going to be able to avoid it.

Again, read section 6.3 "Conversions" of the standard.  It sounds like
you're going to have to explicitly cover all the cases in that section
(except for null pointer constants, which exist only in source code).

[...]

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#387391

FromThiago Adams <thiago.adams@gmail.com>
Date2024-08-08 08:35 -0300
Message-ID<v92aha$3u7l7$2@dont-email.me>
In reply to#387382
On 07/08/2024 17:08, Keith Thompson wrote:
> Thiago Adams <thiago.adams@gmail.com> writes:
>> How cast works?
>> Does it changes the memory?
>> For instance, from "unsigned int" to "signed char".
>> Is it just like discarding bytes or something else?


I also curious about how bool works.

Values converted to bool became 0 or 1.
When this conversion happens, at read or write? Both?

How much does it cost?

I also learned we cannot cast a pointer to nullptr_t.

But we can read a union with nullptr. In this case the value is 0
similar of what happens with bool.

Sample

----------------

#include <stdio.h>

struct value {
     int type;
     union{
         unsigned int ui;
         _Bool b;
         typeof(nullptr) p;
     } ;
};

int main(){

    struct value v;
    v.ui =  123;
    printf("%d / ", v.ui); //123
    printf("%d / ", v.b);  //1
    printf("%p", v.p);     //(nil)
}

--------

Using compiler explorer to understand bool.

void f(int i)
{
   bool b  = i;
   printf("%d / ", b);
}


cmp     dword ptr [rbp - 4], 0  //i think it checks 0 here
setne   al
and     al, 1
mov     byte ptr [rbp - 5], al

I think it convert at write in this case..but for union it converts
when we read. This is why
printf("%d / ", v.b);  //1
prints 1


void f()
{
    union {
     unsigned int ui;
     _Bool b;
    }  v;
    v.ui =  123;
    printf("%d / ", v.b);
}

Where b.b is converted to 1?

f:
         push    rbp
         mov     rbp, rsp
         sub     rsp, 16
         mov     dword ptr [rbp - 4], 123
         mov     al, byte ptr [rbp - 4]
         and     al, 1
         movzx   esi, al
         lea     rdi, [rip + .L.str]
         mov     al, 0
         call    printf@PLT
         add     rsp, 16
         pop     rbp
         ret



I think is at
al, 1
so the compiler uses 123 & 1 to cast number to bool.




[toc] | [prev] | [next] | [standalone]


#387407

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2024-08-08 12:39 -0700
Message-ID<87y156953x.fsf@nosuchdomain.example.com>
In reply to#387391
Thiago Adams <thiago.adams@gmail.com> writes:
> On 07/08/2024 17:08, Keith Thompson wrote:
>> Thiago Adams <thiago.adams@gmail.com> writes:
>>> How cast works?
>>> Does it changes the memory?
>>> For instance, from "unsigned int" to "signed char".
>>> Is it just like discarding bytes or something else?
>
> I also curious about how bool works.
>
> Values converted to bool became 0 or 1.
> When this conversion happens, at read or write? Both?

I don't know what you mean by that.

A conversion takes a value of some type and yields a value of some
(other) type.  If the target type is bool, the result is false (0) if
the operand is equal to zero, true (1) otherwise.

A cast is simply an explicit conversion.  Explict and implicit
conversions do the same thing.  (Some conversions can only be done
explicitly.)

A converted value does not "become" 0 or 1; the conversion *yields*
0 or 1.  The value of (bool)42 is 1, but 42 is still 42.

> How much does it cost?

It depends on what code the compiler generates; the language doesn't
address that.  It could be free if the result isn't used and the
compiler optimizes it away.

[...]

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#387413

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2024-08-08 18:40 -0400
Message-ID<v93hgg$9q8p$1@dont-email.me>
In reply to#387391
Thiago Adams <thiago.adams@gmail.com> writes:
...
> I also curious about how bool works.
>
> Values converted to bool became 0 or 1.
> When this conversion happens, at read or write? Both?

You can take a value obtained by reading an object, or a value produced
by evaluating an expression, and convert that value to a different type.
That value can later be stored in an object, or it could be used as one
of the operands for an expression. The conversion isn't associated with
either the read or the write. Many conversions occur implicitly, a cast
is used to explicitly make a conversion occur.

int x = 3;
bool b = x;

In the above code, an implicit conversion from int to bool occurs after
reading the value of 3 from x, and occurs before writing to bool.

b = !(bool)(x-3);

In this code, the conversion occurs after the value of 3 is retrieved
from x, and after 3 is subtracted from it. That result of 0 is then
converted to bool, and then the ! operator is applied to it. Finally,
the result is written to b. So you see, it doesn't make sense to connect
the conversion with either the read or the write.

[toc] | [prev] | [next] | [standalone]


#387489

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2024-08-11 17:15 -0700
Message-ID<86bk1yk35e.fsf@linuxsc.com>
In reply to#387413
James Kuyper <jameskuyper@alumni.caltech.edu> writes:

> Thiago Adams <thiago.adams@gmail.com> writes:
> ...
>
>> I also curious about how bool works.
>>
>> Values converted to bool became 0 or 1.
>> When this conversion happens, at read or write?  Both?
>
> You can take a value obtained by reading an object, or a value produced
> by evaluating an expression, and convert that value to a different type.
> That value can later be stored in an object, or it could be used as one
> of the operands for an expression.  The conversion isn't associated with
> either the read or the write.  Many conversions occur implicitly, a cast
> is used to explicitly make a conversion occur.
>
> int x = 3;
> bool b = x;
>
> In the above code, an implicit conversion from int to bool occurs after
> reading the value of 3 from x, and occurs before writing to bool.
>
> b = !(bool)(x-3);
>
> In this code, the conversion occurs after the value of 3 is retrieved
> from x, and after 3 is subtracted from it.  That result of 0 is then
> converted to bool, and then the ! operator is applied to it.  Finally,
> the result is written to b.  So you see, it doesn't make sense to connect
> the conversion with either the read or the write.

The assignment statement

    b = !(bool)(x-3);

performs two conversions.  The (bool) cast converts an int value
to a bool value.  The assignment to b converts the value of the !
subexpression (which is of type int) to bool before assigning it.

Assignment operators always convert the value being assigned to
the type of the assignment expression, even if the two types
are the same.

[toc] | [prev] | [next] | [standalone]


#387395 — Is there an audio book version (Was: how cast works?)

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2024-08-08 16:19 +0000
SubjectIs there an audio book version (Was: how cast works?)
Message-ID<v92r70$fd84$2@news.xmission.com>
In reply to#387382
In article <87frrg9jud.fsf@nosuchdomain.example.com>,
Keith Thompson  <Keith.S.Thompson+u@gmail.com> wrote:
>Thiago Adams <thiago.adams@gmail.com> writes:
>> How cast works?
>> Does it changes the memory?
>> For instance, from "unsigned int" to "signed char".
>> Is it just like discarding bytes or something else?
>
>It depends on the source and target types.
>
>A cast is an explicit conversion.  It takes a value of some type and
>yields a value of some (other) type -- or of the same type.  The
>semantics of a conversion are not affected by whether it's done
>explicitly or implicitly.
>
>The rules depend on the source and target types, and are specified in
>the standard, section 6.3 "Conversions".  You'll need to read the whole
>thing.

What if he is a Trumper and can't read?  What then?

-- 
Modern Conservative: Someone who can take time out from demanding more
flag burning laws, more abortion  laws, more drug laws, more obscenity
laws, and more police authority  to make warrantless arrests to remind
us that we need to "get the government off our backs".

[toc] | [prev] | [next] | [standalone]


Page 6 of 7 — ← Prev page 1 2 3 4 5 [6] 7  Next page →

Back to top | Article view | comp.lang.c


csiph-web