GCC optimization re-order statements

Segher Boessenkool segher@kernel.crashing.org
Sat Jun 12 14:03:36 GMT 2021


On Sat, Jun 12, 2021 at 01:46:14PM +0200, David Brown wrote:
> On 12/06/2021 03:45, Segher Boessenkool wrote:
> > On Fri, Jun 11, 2021 at 01:56:40PM +0200, David Brown wrote:
> >> If the compiler knows that on the target in question, it is perfectly
> >> safe (i.e., no signals or anything else) to dereference a null pointer,
> >> then in your original "f" the compiler could read *p before it tests p
> >> for null, but it could not do the printf before the test.  (Sometimes
> >> for embedded systems the compiler knows that reading via a null pointer
> >> is safe.)
> > 
> > But note that this is undefined behaviour in standard C (a null pointer
> > is required to compare unequal to any pointer to any object or function
> > (6.3.2.3/3), and the indirection operator on any operand that does not
> > point to a function or object is undefined behaviour (6.5.3.2/4)).
> > 
> > It can be extremely useful to do support this, of course :-)
> 
> It is undefined behaviour in the standard, but it is supported in some
> compilers.  (To be honest, I can't remember if it is supported in any
> gcc targets.)

GCC has the target hook TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID:
  bool TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID (addr_space_t as)
  Define this to modify the default handling of address 0 for the
  address space.  Return true if 0 should be considered a valid address.

Only x86 implements this currently, for allowing addresses %fs:0 and
%gs:0 .

> In some microcontrollers for small embedded systems,
> address 0 is part of the ram - and if you only have 1 KB ram, you don't
> want to waste a byte as inaccessible.  On some microcontrollers I have
> used, address 0 is part of the hardware registers for controlling pins,
> peripherals, etc.  And often it is part of the flash and you might want
> to read that for doing CRC checks or other integrity checks.  Of course,
> in many of these cases you would (or could) use volatile accesses, and
> the compiler will never mess with those.

Yeah, and some have address spaces (or address extensions, or whatever
it is called on that arch) on the hardware as well.  Address zero in a
non-default address space should not be considered a null pointer then
usually.

> There are also a few systems where reading address 0 is guaranteed to
> return 0, or guaranteed to cause a fault.  Compilers might have modified
> behaviour to take that into account (since the standards don't impose
> any requirements about how accessing address 0 works).

Yup, the standard is very careful not to :-)  Converting the integer
zero to a pointer gives a null pointer, that is how far it goes :-)


Segher


More information about the Gcc-help mailing list