Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The <strong>C Standard</strong> is quite clear on it. The effective type of the object named by <code>p</code> is <code>void*</code>, because it has a declared type, see <code>6.5/6</code>. The aliasing rules in C99 apply to reads <em>and</em> writes, and the write to <code>void*</code> through an <code>unsigned</code> lvalue in <code>(1)</code> is undefined behavior according to <code>6.5/7</code>. </p> <p>In contrast, the <code>memcpy</code> of <code>(2)</code> is fine, because <code>unsigned char*</code> can alias any object (<code>6.5/7</code>). The Standard defines <code>memcpy</code> at <code>7.21.2/1</code> as </p> <blockquote> <p>For all functions in this subclause, each character shall be interpreted as if it had the type unsigned char (and therefore every possible object representation is valid and has a different value).</p> <p>The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined.</p> </blockquote> <p>However if there exist a use of <code>p</code> afterwards, that might cause undefined behavior depending on the bitpattern. If such a use does not happen, that code is fine in C. </p> <hr> <p>According to the <strong>C++ Standard</strong>, which in my opinion is far from clear on the issue, i think the following holds. Please don't take this interpretation as the only possible - the vague/incomplete specification leaves a lot of room for speculation. </p> <p>Line <code>(1)</code> is problematic because the alignment of <code>&amp;p</code> might not be ok for the <code>unsigned</code> type. It changes the type of the object stored in <code>p</code> to be <code>unsigned int</code>. As long as you don't access that object later on through <code>p</code>, aliasing rules are not broken, but alignment requirements might still be. </p> <p>Line <code>(2)</code> however has no alignment problems, and is thus valid, as long as you don't access <code>p</code> afterwards as a <code>void*</code>, which might cause undefined behavior depending on how the <code>void*</code> type interprets the stored bitpattern. I don't think that the type of the object is changed thereby. </p> <p>There is a long <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29286" rel="noreferrer">GCC Bugreport</a> that also discusses the implications of a write through a pointer that resulted from such a cast and what the difference to placement-new is (people on that list aren't agreeing what it is). </p>
 

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