Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #158407 > unrolled thread
| Started by | wij <wyniijj@gmail.com> |
|---|---|
| First post | 2021-01-17 06:09 -0800 |
| Last post | 2021-01-17 17:17 +0000 |
| Articles | 11 on this page of 31 — 11 participants |
Back to article view | Back to comp.lang.c
Usage of union wij <wyniijj@gmail.com> - 2021-01-17 06:09 -0800
Re: Usage of union wij <wyniijj@gmail.com> - 2021-01-17 06:18 -0800
Re: Usage of union James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-17 10:39 -0500
Re: Usage of union wij <wyniijj@gmail.com> - 2021-01-17 08:41 -0800
Re: Usage of union Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2021-01-17 17:07 +0000
Re: Usage of union James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-17 12:29 -0500
Re: Usage of union Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2021-01-17 17:47 +0000
Re: Usage of union James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-17 14:22 -0500
Re: Usage of union Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-20 07:03 -0800
Re: Usage of union wij <wyniijj@gmail.com> - 2021-01-20 09:33 -0800
Re: Usage of union Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-23 08:01 -0800
Re: Usage of union Jorgen Grahn <grahn+nntp@snipabacken.se> - 2021-01-26 20:28 +0000
Re: Usage of union wij <wyniijj@gmail.com> - 2021-01-27 03:15 -0800
Re: Usage of union James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-17 12:19 -0500
Re: Usage of union Bonita Montero <Bonita.Montero@gmail.com> - 2021-01-20 19:24 +0100
Re: Usage of union Christian Hanné <the.hanne@gmail.com> - 2021-01-20 19:31 +0100
Re: Usage of union Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-17 07:54 -0800
Re: Usage of union Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-17 08:17 -0800
Re: Usage of union wij <wyniijj@gmail.com> - 2021-01-17 09:07 -0800
Re: Usage of union James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-17 12:32 -0500
Re: Usage of union Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-20 05:56 -0800
Re: Usage of union Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-20 09:52 -0800
Re: Usage of union Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-20 06:09 -0800
Re: Usage of union Bonita Montero <Bonita.Montero@gmail.com> - 2021-01-20 19:41 +0100
Re: Usage of union scott@slp53.sl.home (Scott Lurndal) - 2021-01-20 18:49 +0000
Re: Usage of union Bonita Montero <Bonita.Montero@gmail.com> - 2021-01-20 20:09 +0100
Re: Usage of union scott@slp53.sl.home (Scott Lurndal) - 2021-01-20 19:25 +0000
Re: Usage of union David Brown <david.brown@hesbynett.no> - 2021-01-20 20:29 +0100
Re: Usage of union Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-20 11:36 -0800
Re: Usage of union James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-01-17 12:14 -0500
Re: Usage of union Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-01-17 17:17 +0000
Page 2 of 2 — ← Prev page 1 [2]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-01-20 05:56 -0800 |
| Message-ID | <86turbogog.fsf@linuxsc.com> |
| In reply to | #158413 |
Andrey Tarasevich <andreytarasevich@hotmail.com> writes:
[context: does the following code have undefined behavior?
union {
uint16_t u16;
uint8_t u8[2];
float flt;
} u;
void t() {
u.u16=0;
assert(u.u8[0]==0);
assert(u.u8[1]==0);
};
(end context)]
> [In C] there's no immediate UB when reading `u8`. In general
> case the potential for UB is still there [because of trap
> representations], but with uint8_t` everything should be fine
> since `uint8_t` is not supposed to have trap representations.
> (BTW, it seems that this is not explicitly spelled out in C
> standard.)
All of the exact-width integer types [u]intN_t, including uint8_t,
cannot have trap representations. The C standard doesn't say this
directly, but it follows pretty immediately from the properties of
exact-width integer types and from the definitions of object
representation and trap representation. (For signed exact-width
types intN_t, section 7.20.2.1 provides a crucial piece of that
deduction, which is easy to miss if one doesn't know to look for
it.)
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2021-01-20 09:52 -0800 |
| Message-ID | <ru9qk5$i7m$1@dont-email.me> |
| In reply to | #158478 |
On 1/20/2021 5:56 AM, Tim Rentsch wrote: > > All of the exact-width integer types [u]intN_t, including uint8_t, > cannot have trap representations. The C standard doesn't say this > directly, but it follows pretty immediately from the properties of > exact-width integer types and from the definitions of object > representation and trap representation. (For signed exact-width > types intN_t, section 7.20.2.1 provides a crucial piece of that > deduction, which is easy to miss if one doesn't know to look for > it.) > Yes, I can see that now. 7.20.2.1 says that all combinations of value-forming bits are "taken" to represent valid values, and 7.20.1.1 says that there are no padding bits in these types. -- Best regards, Andrey Tarasevich
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-01-20 06:09 -0800 |
| Message-ID | <86pn1zog3l.fsf@linuxsc.com> |
| In reply to | #158412 |
Andrey Tarasevich <andreytarasevich@hotmail.com> writes:
> On 1/17/2021 6:09 AM, wij wrote:
>
>> My understanding of union is from the low level point of view,
>> worked so far OK. But confused again by reading the meaning of how
>> C++11 says it treats union.
>>
>> https://stackoverflow.com/questions/11373203/
>> accessing-inactive-union-member-and-undefined-behavior
>>
>> //-----------------------------
>> union {
>> uint16 u16;
>> uint8 u8[2];
>> float flt;
>> } u;
>>
>> void t() {
>> u.u16=0;
>>
>> assert(u.u8[0]==0); // using u8 member is UB
>> assert(u.u8[1]==0); // then, what does UB mean?
>> // might the lines above trigger
>> // Undefined Behavior?
>> };
>> //-----------------------------
>>
>> If I store values via member u16, surely I CAN use other members.
>
> [Briefly, C defines the behavior, C++ makes the behavior undefined
> in all cases.]
>
> In the above example you are trying to use union for "type punning",
> i.e for memory reinterpretation. This is not exactly what unions are
> for.
It is exactly one of the uses that unions are for.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-01-20 19:41 +0100 |
| Message-ID | <ru9tga$7i8$1@dont-email.me> |
| In reply to | #158479 |
>> In the above example you are trying to use union for "type punning", >> i.e for memory reinterpretation. This is not exactly what unions are >> for. > It is exactly one of the uses that unions are for. Yes, it's the only way to safely circumvent the strict aliasing rule.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-01-20 18:49 +0000 |
| Message-ID | <gX_NH.14188$PB3.9015@fx18.iad> |
| In reply to | #158496 |
Bonita Montero <Bonita.Montero@gmail.com> schrieb: >>> In the above example you are trying to use union for "type punning", >>> i.e for memory reinterpretation. This is not exactly what unions are >>> for. > >> It is exactly one of the uses that unions are for. > >Yes, it's the only way to safely circumvent the strict aliasing rule. -fno-strict-aliasing
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-01-20 20:09 +0100 |
| Message-ID | <ru9v65$kc4$1@dont-email.me> |
| In reply to | #158497 |
>>> It is exactly one of the uses that unions are for. >> Yes, it's the only way to safely circumvent the strict aliasing rule. > -fno-strict-aliasing -fno-strict-aliasing doesn't make casted aliasing valid, it only prevents compiler-warnings.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-01-20 19:25 +0000 |
| Message-ID | <Ms%NH.27753$MW1.15087@fx20.iad> |
| In reply to | #158499 |
Bonita Montero <Bonita.Montero@gmail.com> writes: >>>> It is exactly one of the uses that unions are for. > >>> Yes, it's the only way to safely circumvent the strict aliasing rule. > >> -fno-strict-aliasing > >-fno-strict-aliasing doesn't make casted aliasing valid, >it only prevents compiler-warnings. Wrong. It instructs the compiler to generate code assuming that anything can be aliased. You've confused it with -Wstrict-aliasing=n.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-01-20 20:29 +0100 |
| Message-ID | <rua0b6$t1s$1@dont-email.me> |
| In reply to | #158499 |
On 20/01/2021 20:09, Bonita Montero wrote: >>>> It is exactly one of the uses that unions are for. > >>> Yes, it's the only way to safely circumvent the strict aliasing rule. > >> -fno-strict-aliasing > > -fno-strict-aliasing doesn't make casted aliasing valid, > it only prevents compiler-warnings. > No, it makes them valid - it changes the semantics of the language (C or C++) to remove the "strict aliasing rule". (There is no such single rule in the standards - but it's a convenient summary of the actual rules.) If you just want to hide the warnings (which would be a ridiculous thing to do), use "-Wno-strict-aliasing". Other than that, the common and definitely safe way to circumvent strict aliasing is to use memcpy.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2021-01-20 11:36 -0800 |
| Message-ID | <rua0nl$unt$1@dont-email.me> |
| In reply to | #158496 |
On 1/20/2021 10:41 AM, Bonita Montero wrote: >>> In the above example you are trying to use union for "type punning", >>> i.e for memory reinterpretation. This is not exactly what unions are >>> for. > >> It is exactly one of the uses that unions are for. > > Yes, it's the only way to safely circumvent the strict aliasing rule. > Not really the only way. A simple cast-based re-interpretation as an array of [signed/unsigned] char is not a violation of strict aliasing rules.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2021-01-17 12:14 -0500 |
| Message-ID | <ru1ra3$d9s$1@dont-email.me> |
| In reply to | #158407 |
On 1/17/21 9:09 AM, wij wrote:
> My understanding of union is from the low level point of view, worked
> so far OK. But confused again by reading the meaning of how C++11 says it treats union.
>
> https://stackoverflow.com/questions/11373203/accessing-inactive-union-member-and-undefined-behavior
>
> //-----------------------------
> union {
> uint16 u16;
> uint8 u8[2];
uint16 and uint8 are not standard-defined types. I didn't notice that
before, I assumed in my previous message that you were actually using
uint16_t and uint8_t, which are standard-defined. I'll continue that
assumption in this message.
> float flt;
> } u;
>
> void t() {
> u.u16=0;
>
> assert(u.u8[0]==0); // using u8 member is UB
> assert(u.u8[1]==0); // then, what does UB mean?
> // might the lines above trigger Undefined Behavior?
> };
> //-----------------------------
>
> If I store values via member u16, surely I CAN use other members.
My previous message explained why you can read u8 or u16 in C. However,
you can't read flt.
On most implementations, float is a 32-bit type, usually IEEE/IEC
single-precision floating point. The standard doesn't specify a minimum
size for the type, but it does impose requirements on its
representations, and if I've calculated correctly, the minimum size
format that can meet those requirements takes up at least 25 bits.
An implementation for which uint8 is supported must have CHAR_BITS == 8,
so sizeof(float) >= 4.
Therefore, after you've set both elements of u8 to 0, there's at least 9
bits used by flt, and more likely 16 of them, that are still
uninitialized. That means you can't guarantee that it's a valid
representation. In particular, it's entirely possible for it to be a
signaling NaN, which means that any attempt to read it could cause your
program to abort.
> What does UB really mean in this situation?
The behavior is actually implementation-defined, not UB, though reading
flt could result in UB if it contains a trap representation (which is
not permitted for uint16.
Undefined Behavior, regardless of it's cause, always means
"behavior, upon use of a nonportable or erroneous program construct or
of erroneous data, for which this International Standard imposes no
requirements" (3.4.3p1).
Note that "undefined behavior" is NOT defined as "behavior which is not
defined". If the C standard doesn't define the behavior, but some other
document (such as the POSIX standard or your compiler's documentation)
does define the behavior, it still qualifies as undefined behavior as
far as the C standard is concerned.
The standard has a note which clarifies how thoroughly "no requirements"
applies: "Possible undefined behavior ranges from ignoring the situation
completely with unpredictable results, to behaving during translation or
program execution in a documented manner characteristic of the
environment (with or without the issuance of a diagnostic message), to
terminating a translation or execution (with the issuance of a
diagnostic message."
It might be impossible for your computer to self-destruct as a result of
executing code with undefined behavior, but not because of anything it
says in the C standard prohibiting that result.
Note that perhaps the single most dangerous way your program might
behave, is precisely the way you erroneously thought it was required to
behave. As a result, you won't notice that your expectations were incorrect.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-01-17 17:17 +0000 |
| Message-ID | <87wnwb7aah.fsf@bsb.me.uk> |
| In reply to | #158407 |
wij <wyniijj@gmail.com> writes:
> My understanding of union is from the low level point of view, worked
> so far OK. But confused again by reading the meaning of how C++11 says
> it treats union.
>
> https://stackoverflow.com/questions/11373203/accessing-inactive-union-member-and-undefined-behavior
>
> //-----------------------------
> union {
> uint16 u16;
> uint8 u8[2];
> float flt;
> } u;
>
> void t() {
> u.u16=0;
>
> assert(u.u8[0]==0); // using u8 member is UB
> assert(u.u8[1]==0); // then, what does UB mean?
> // might the lines above trigger Undefined Behavior?
> };
> //-----------------------------
>
> If I store values via member u16, surely I CAN use other members.
> What does UB really mean in this situation?
Yes, it's fine. Reading from a member that was not the last one
assigned to simply reinterprets the bits. This has been made explicit
in recent standards (since C99) but the general opinion is that this is
what was always intended, since the clarification is in a footnote.
Of course, problems can occur if the value that results from this
reinterpretation is a trap representation, nut you are unlikely to come
across that situation and, anyway, it can't happen with uint8.
--
Ben.
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web