<div>> But the pointer itself does constitute another separate object.  And<br/>
that object is the one that is stored in the union (the uint8_t data is<br/>
not stored in the union, but in some other allocated memory (probably)).<br/>
<br/>
The pointer to structure's field does not stored in the structure. And reading the pointer to the field is just adding an offset to the object pointer.<br/>
<br/>
Why do you ignore my suggestion to replace "p->base" with "(uint8_t *) p" and try to understand the purpose of the object, 'base' and 'offset'? Instead you digging the specifications to prove the validation software behavior.<br/>
<br/>
--<br/>
Max<br/><br/>-----Original Message-----<br/>From: Alejandro Colomar <alx.manpages@gmail.com><br/>To: Max Romanov <max.romanov@gmail.com>, Andrew Clayton <andrew@digital-domain.net><br/>Cc: unit@nginx.org<br/>Sent: сб, 18 июн. 2022 2:15<br/>Subject: Re: [PATCH 06/11] Sptr: avoided potentially undefined behaviour.<br/><br/></div>Hi Max <br/>
<br/>
On 6/18/22 01:04, Max Romanov wrote: <br/>
> I'm sorry to be a pain, <br/>
<br/>
No problem :) <br/>
<br/>
  but the key thing is: ".. read from another <br/>
> object..". <br/>
<br/>
In this case, ISO C uses the term object to refer to a broader concept,  <br/>
that includes any variable. <br/>
<br/>
3.15/1,2: <br/>
" <br/>
object <br/>
region of data storage in the execution environment, the contents of  <br/>
which can represent values <br/>
" <br/>
<br/>
> In the statement you are trying to "fix", the "base" does not  <br/>
> actually _read_ from the object (structure, to be precise), instead the  <br/>
> address of the structure itself used. In other words, "p->base" is a  <br/>
> shortcut for "(uint8_t *) p". <br/>
<br/>
the region of data storage pointed to by `p->base` would be an object  <br/>
(of type uint8_t, or maybe uint8_t[]). <br/>
<br/>
But the pointer itself does constitute another separate object.  And  <br/>
that object is the one that is stored in the union (the uint8_t data is  <br/>
not stored in the union, but in some other allocated memory (probably)). <br/>
<br/>
Since we are reading a member of the union (and each member is an  <br/>
object, by definition, even if it's a pointer), and storing the value  <br/>
into another member of the union, that's not valid. <br/>
<br/>
As pointed by @supercat in StackOverflow (in the link I provided), the  <br/>
rationale was probably to allow compilers to do some optimizations, or  <br/>
for example, copy byte by byte; in archs where the union members are  <br/>
larger than a register, this will definitely cause a bug; in archs where  <br/>
the union members fit into a register (as in our case), the code is  <br/>
likely to work, but the standard makes no guarantees about it, and a  <br/>
compiler may still do bad stuff.  It's better to be safe. <br/>
<br/>
Cheers, <br/>
<br/>
Alex <br/>
>> <<a href="https://stackoverflow.com/a/72652427/6872717">https://stackoverflow.com/a/72652427/6872717</a>  <br/>
--  <br/>
Alejandro Colomar <br/>
<<a href="http://www.alejandro-colomar.es">http://www.alejandro-colomar.es</a>/> <br/>