Note that there are some explanatory texts on larger screens.

plurals
  1. POAccessing static member through invalid pointer: guaranteed to "work"?
    primarykey
    data
    text
    <p><strong>Setup</strong></p> <p>Given this user-defined type:</p> <pre><code>struct T { static int x; int y; T() : y(38); }; </code></pre> <p>and the requisite definition placed somewhere useful:</p> <pre><code>int T::x = 42; </code></pre> <p>the following is the canonical way to stream the <code>int</code>'s value to <em>stdout</em>:</p> <pre><code>std::cout &lt;&lt; T::x; </code></pre> <p><strong>Control</strong></p> <p>Meanwhile, the following is (of course) invalid due to an instance of <code>T</code> not existing:</p> <pre><code>T* ptr = NULL; // same if left uninitialised std::cout &lt;&lt; ptr-&gt;y; </code></pre> <p><strong>Question</strong></p> <p>Now consider the horrid and evil and bad following code:</p> <pre><code>T* ptr = NULL; std::cout &lt;&lt; ptr-&gt;x; // remember, x is static </code></pre> <p>Dereferencing <code>ptr</code> is invalid, as stated above. Even though no physical memory dereference takes place here, I <em>believe</em> that it still counts as one, making the above code UB. Or... does it?</p> <p>14882:2003 5.2.5/3 states explicitly that <code>a-&gt;b</code> is converted to <code>(*(a)).b</code>, and that:</p> <blockquote> <p>The postfix expression before the dot or arrow is evaluated; This evaluation happens even if the result is unnecessary to determine the value of the entire postfix expression, for example if the id-expression denotes a static member.</p> </blockquote> <p>But it's not clear whether "evaluation" here involves an actual dereference. In fact neither 14882:2003 nor n3035 seem to explicitly say either way whether the pointer-expression has to evaluate to a pointer to a valid instance when dealing with static members.</p> <p>My question is, just how invalid is this? Is it really specifically prohibited by the standard (even though there's no physical dereference), or is it just a quirk of the language that we can probably get away with? And even if it is prohibited, to what extent might we expect GCC/MSVC/Clang to treat it safely anyway?</p> <p>My g++ 4.4 appeared to produce code that never attempts to push the [invalid] <code>this</code> pointer onto the stack, with optimisations turned off.</p> <p><strong>BTW</strong> If <code>T</code> were polymorphic then that would not affect this, as static members cannot be virtual.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload