Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It seems there are two things going on that need to be understood:</p> <ul> <li><code>printf()</code> conversion specifiers</li> <li>Integral conversions</li> </ul> <p>And two more things that help make sense of your output:</p> <ul> <li>Argument promotion for variadic function arguments</li> <li>Two's complement representation</li> </ul> <p>First, <code>printf()</code> is a variadic function. It doesn't know what the types of its arguments are (other than the format string), so you have to use conversion specifiers to tell it how to interpret the arguments. These arguments are subject to the "default argument promotions" such that your 3-bit bit fields are being promoted to <code>int</code>s.</p> <p>You are using conversions specifiers (<code>%d</code>, <code>%u</code>, and <code>%d</code>) that do not match the signedness of your data, so you will get undefined behavior that depends on how your data is actually represented in memory.</p> <p>Second, the C11 standard states:</p> <blockquote> <p><strong>6.3.1.3</strong> <em>Signed and unsigned integers</em></p> <ul> <li><p>When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged. </p></li> <li><p>Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. </p></li> <li><p>Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.</p></li> </ul> </blockquote> <p>(As far as I can tell, the details relevant here have been true at least since C89.)</p> <p>This tells us a couple things about your code:</p> <ul> <li><p>When you assign <code>-1</code> to an <code>unsigned int</code>, <code>UINT_MAX + 1</code> is added to it, giving <code>UINT_MAX</code>, or <code>4294967295</code> for 32-bit integers.</p></li> <li><p>When you try to assign <code>5</code> to a 3-bit signed bit field, the result is implementation-defined.</p></li> </ul> <p>So you've got both undefined and implementation-defined behavior, but we can still try to make sense of your output, just for fun. I'm assuming 32-bit integers and <a href="http://en.wikipedia.org/wiki/Two%27s_complement" rel="nofollow">two's complement</a> representation.</p> <p>Your system represents the <code>4294967295</code> stored in <code>x</code> as <code>11111111 11111111 11111111 11111111</code>. When you told <code>printf()</code> that the argument you were passing it was signed, those same bits are interpreted as <code>-1</code>, which is the output you got.</p> <p>For <code>s.c</code>, the implementation-defined behaviour you seem to have gotten is straightforward: the three bits <code>101</code>representing <code>5</code> got stored as-is. That means that with the correct conversion specifier, <code>printf()</code> should show <code>s.c</code> as <code>-3</code>.</p> <p>Here are the values you've assigned:</p> <pre><code>s.i = 101 s.c = 101 x = 11111111 11111111 11111111 11111111 </code></pre> <p>The 3-bit values are promoted to 32-bit by left-padding with <code>0</code> for the unsigned value and repeating the sign for the signed value:</p> <pre><code>s.i = 00000000 00000000 00000000 00000101 s.c = 11111111 11111111 11111111 11111101 x = 11111111 11111111 11111111 11111111 </code></pre> <p>Which, when interpreted as signed, unsigned, and signed integers gives:</p> <pre><code>s.i=5 s.c=4294967293 x=-1 </code></pre> <p>The <code>x=-1</code> suggests to me that you are in fact using a two's complement representation (which was a pretty safe bet, anyway), and the output for <code>s.c</code> suggests that your <code>int</code>s are 32 bits wide.</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