7

In the comments to this answer I stumbled about a discussion about the meaning of "valid pointer". Since I think that that is interesting in general:

What is a "valid pointer" in C++?

In particular:

Is reinterpret_cast<const void*>(0x1) a valid pointer?

Community
  • 1
  • 1
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • Perhaps it might help if you reread the other post with compile-time constant propagation in mind, which is one of the big problems that `constexpr` was designed to solve. – Kerrek SB Jun 25 '14 at 00:59

1 Answers1

10

The Standard places implementations into two general categories:

  • Those with strict pointer safety
  • Those with relaxed pointer safety

Your expression definitely is not a safely-derived pointer, so it's invalid in the first.

Quote from 3.7.4.3:

An implementation may have relaxed pointer safety, in which case the validity of a pointer value does not depend on whether it is a safely-derived pointer value. Alternatively, an implementation may have strict pointer safety, in which case a pointer value referring to an object with dynamic storage duration that is not a safely-derived pointer value is an invalid pointer value unless the referenced complete object has previously been declared reachable (20.7.4). [ Note: the effect of using an invalid pointer value (including passing it to a deallocation function) is undefined, see 3.7.4.2. This is true even if the unsafely-derived pointer value might compare equal to some safely-derived pointer value. — end note ] It is implementation defined whether an implementation has relaxed or strict pointer safety.

For implementations with relaxed safety, it doesn't matter how the pointer value is gotten, just that (3.9.2):

A valid value of an object pointer type represents either the address of a byte in memory (1.7) or a null pointer.

Is 0x1 a valid memory address on your system? Well, for some embedded systems it is. For most OSes using virtual memory, the page beginning at zero is reserved as invalid.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • 1
    I'm not sure if that's the right kind of reference. The "pointer safety" stuff is about opaquely supporting garbage collection, I think. My point about valid pointers is a consequence of the various "Expression" rules, e.g. what you can add, subtract and dereference. – Kerrek SB Jun 25 '14 at 00:49
  • @KerrekSB: Pointer values can be valid, and still lead to undefined behavior if used in certain ways (example: passing the address of an automatic variable to `::operator delete()`) – Ben Voigt Jun 25 '14 at 00:52
  • Regarding your edit: This is getting a bit confused, because the question is in reference to `constexpr` pointers, and `constexpr` explicitly forbids expressions that would have undefined behaviour (e.g. out-of-bound array access). So while you might be able to use a platform-defined, reinterpreted address, it's not allowed as a constant expression... (though I suppose we know that). – Kerrek SB Jun 25 '14 at 00:58
  • 1
    @KerrekSB: What undefined behavior? It's properly aligned, and it hasn't been dereferenced. – Ben Voigt Jun 25 '14 at 01:12
  • It's not a legal constant expression by virtue of the fact that `reinterpret_cast` is used, not because of any undefined behavior. – Ben Voigt Jun 25 '14 at 01:19
  • I wasn't clear enough - I was trying to say that you cannot prove statically that it's *not* undefined behaviour. You couldn't even prove that `p + 0` is not undefined behaviour. It *might* be OK, but you cannot know (from within the language). If it's OK on your platform, that's external information that you're bringing in. – Kerrek SB Jun 25 '14 at 08:51