<pre><code>struct foo { unsigned x:1; } f;
printf("%d\n", (int)sizeof(f.x = 1));
</code></pre>

<p>What is the expected output and why?  Taking the size of a bitfield lvalue directly isn't allowed. But by using the assignment operator, it seems we can still take the size of a bitfield type.</p>

<p>What is the "size of a bitfield in bytes"?  Is it the size of the storage unit holding the bitfield?  Is it the number of bits taken up by the bf rounded up to the nearest byte count?</p>

<p>Or is the construct undefined behavior because there is nothing in the standard that answers the above questions?  Multiple compilers on the same platform are giving me inconsistent results.</p>

[{'answer_id': 81348, 'author': 'Jason Dagit', 'author_id': 5113, 'author_profile': 'https://Stackoverflow.com/users/5113', 'pm_score': 0, 'selected': False, 'text': '<p>Wouldn\'t</p>\n\n<pre><code>(f.x = 1)\n</code></pre>\n\n<p>be an expression evaluating to true (technically in evaluates to result of the assignment, which is 1/true in this case), and thus,</p>\n\n<pre><code>sizeof( f.x = 1)\n</code></pre>\n\n<p>is asking for the size of true in terms of how many chars it would take to store it?</p>\n\n<p>I should also add that the Wikipedia article on <a href="http://en.wikipedia.org/wiki/Sizeof" rel="nofollow noreferrer">sizeof</a> is nice.  In particular, they say "sizeof is a compile-time operator that returns the size, in multiples of the size of char, of the variable or parenthesized type-specifier that it precedes."</p>\n\n<p>The article also explains that sizeof works on expressions.</p>\n'}, {'answer_id': 81407, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<pre><code>sizeof( f.x = 1)\n</code></pre>\n\n<p>returns 1 as its answer. The sizeof(1) is presumably the size of an integer on the platform you are compiling on, probably either 4 or 8 bytes.</p>\n'}, {'answer_id': 81409, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>No, you must be thinking of the == operator, which yields a "boolean" expression of type int in C and indeed bool in C++.</p>\n\n<p>I think the expression will convert the value 1 to the correspondin bitfield type and assign it to the bitfield. The result should also be a bitfield type because there are no hidden promotions or conversions that I can see.</p>\n\n<p>Thus we are effectively getting access to the bitfield type.</p>\n\n<p>No compiler diagnostic is required because "f.x = 1" isn\'t an lvalue, i.e. it does not designate the bitfield directly. It\'s just a value of type "unsigned :1".</p>\n\n<p>I\'m specifically using "f.x = 1" because "sizeof f.x" takes the size of a bitfield lvalue, which is clearly not allowed.</p>\n'}, {'answer_id': 81411, 'author': 'CL.', 'author_id': 11654, 'author_profile': 'https://Stackoverflow.com/users/11654', 'pm_score': 1, 'selected': False, 'text': '<p>Trying to get the size of a bitfield isn\'t legal, as you have seen. (<code>sizeof</code> returns the size in bytes, which wouldn\'t make much sense for a bitfield.)</p>\n\n<p><code>sizeof(f.x = 1)</code> will return the size of the type of the expression. Since C doesn\'t have a real "bitfield type", the expression (here: an assignment expression) usually gets the type of the bit field\'s base type, in your example <code>unsigned int</code>, but it is possible for a compiler to use a smaller type internally (in this case probably <code>unsigned char</code> because it\'s big enough for one bit).</p>\n'}, {'answer_id': 81413, 'author': 'mana', 'author_id': 12016, 'author_profile': 'https://Stackoverflow.com/users/12016', 'pm_score': 0, 'selected': False, 'text': '<p>The </p>\n\n<pre><code>(f.x = 1)\n</code></pre>\n\n<p><strong>is not an expression, it is an assignment</strong> and thus returns the assigned value. In this case, the size of that value depends on the variable, it has been assigned to. </p>\n\n<pre><code>unsigned x:1\n</code></pre>\n\n<p>has 1 Bit and its sizeof returns 1 byte (8 bit alignment)</p>\n\n<p>If you would use </p>\n\n<pre><code>unsigned x:12\n</code></pre>\n\n<p>then the sizeof(f.x = 1) would return 2 byte (again because of the 8 bit alignment)</p>\n'}, {'answer_id': 81424, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': "<blockquote>\n  <p>The sizeof(1) is presumably the size of an integer on the platform you are compiling on, probably either 4 or 8 bytes.</p>\n</blockquote>\n\n<p>Note that I'm NOT taking sizeof(1), which is effectively sizeof(int). Look close, I'm taking sizeof(f.x = 1), which should effectively be sizeof(bitfield_type).</p>\n\n<p>I'd like to see a reference to something that tells me whether the construct is legal. As an added bonus, it would be nice if it told me what sort of result is expected.</p>\n\n<p>gcc certainly disagrees with the assertion that sizeof(bitfield_type) should be the same as sizeof(int), but only on some platforms.</p>\n"}, {'answer_id': 81438, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<blockquote>\n  <p>Trying to get the size of a bitfield isn\'t legal, as you have seen. (sizeof returns the size in bytes, which wouldn\'t make much sense for a bitfield.)</p>\n</blockquote>\n\n<p>So are you stating that the behavior is undefined, i.e. it has the same degree of legality as "*(int *)0 = 0;", and compilers can choose to fail to handle this sensibly?</p>\n\n<p>That\'s what I\'m trying to find out. Do you assume that it\'s undefined by omission, or is there something that explicitly declares it as illegal?</p>\n'}, {'answer_id': 81500, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': "<blockquote>\n  <p>is not an expression, it is an assignment and thus returns the assigned value. In this case, the size of that value depends on the variable, it has been assigned to. </p>\n</blockquote>\n\n<p>First, it <strong>IS</strong> an expression containing the assignment operator.</p>\n\n<p>Second, I'm quite aware of what's happening in my example :)</p>\n\n<blockquote>\n  <p>then the sizeof(f.x = 1) would return 2 byte (again because of the 8 bit alignment)</p>\n</blockquote>\n\n<p>Where did you get this? Is this what happens on a particular compiler that you have tried, or are these semantics stated in the standard? Because I haven't found any such statements. I want to know whether the construct is guaranteed to work at all.</p>\n"}, {'answer_id': 81577, 'author': 'mana', 'author_id': 12016, 'author_profile': 'https://Stackoverflow.com/users/12016', 'pm_score': 0, 'selected': False, 'text': '<p>in this second example, if you would define your struct as a</p>\n\n<pre><code>struct foo { unsigned x:12} f;\n</code></pre>\n\n<p>and then write a value like 1 into f.x - it uses 2 Bytes because of the alignment. If you do an assignment like</p>\n\n<pre><code>f.x = 1;\n</code></pre>\n\n<p>and this returns the assigned value. This is quite similar to </p>\n\n<pre><code>int a, b, c;\na = b = c = 1;\n</code></pre>\n\n<p>where the asignment is evaluated from right to left. c = 1 assigns 1 to the variable c and this asignment returns the assigned value and assigns it to b (and so forth) until 1 is assigned to a</p>\n\n<p>it is equal to</p>\n\n<pre><code>a = ( b = ( c = 1 ) )\n</code></pre>\n\n<p>in your case, the sizeof gets the size of your asignment, wich is <strong>NOT</strong> a bitfield, but the variable assigned to it.</p>\n\n<pre><code>sizeof ( f.x = 1)\n</code></pre>\n\n<p>does not return the bitfields size, but the variable assigment which is a 12 bit representation of the 1 (in my case) and therefore sizeof() returns 2 byte (because of the 8bit aligment)</p>\n'}, {'answer_id': 81622, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': "<p>Look, I understand full well what I'm doing with the assignment trick.</p>\n\n<p>You are telling me that the size of a bitfield type is rounded up to the cloest byte count, which is one option I listed in the initial question. But you didn't back it up with references.</p>\n\n<p>In particular, I have tried various compilers which give me sizeof(int) instead of sizeof(char) EVEN if I apply this to a bitfield with only has a single bit.</p>\n\n<p>I wouldn't even mind if multiple compilers randomly get to choose their own interpretation of this construct. Certainly bitfield storage allocation is quite implementation-defined.</p>\n\n<p>However, I really do want to know whether the construct is <strong>GUARANTEED</strong> to work and yield <strong>SOME</strong> value.</p>\n"}, {'answer_id': 83343, 'author': 'CL.', 'author_id': 11654, 'author_profile': 'https://Stackoverflow.com/users/11654', 'pm_score': 2, 'selected': False, 'text': '<p>The C99 Standard (<a href="http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf" rel="nofollow noreferrer">PDF of latest draft</a>) says in section 6.5.3.4 about <code>sizeof</code> constraints:</p>\n\n<blockquote>\n  <p>The <code>sizeof</code> operator shall not be applied to an expression that has function type or an\n  incomplete type, to the parenthesized name of such a type, or to an expression that\n  designates a bit-field member.</p>\n</blockquote>\n\n<p>This means that applying <code>sizeof</code> to an <em>assignment expression</em> is allowed.</p>\n\n<p>6.5.16.3 says:</p>\n\n<blockquote>\n  <p>The type of an assignment expression is the type of the left operand ...</p>\n</blockquote>\n\n<p>6.3.1.1.2 says regarding integer promotions:</p>\n\n<blockquote>\n  <p>The following may be used in an expression wherever an int or unsigned int may be used:</p>\n  \n  <ul>\n  <li>...</li>\n  <li>A bit-field of type <code>_Bool</code>, <code>int</code>, <code>signed int</code>, or <code>unsigned int</code>.</li>\n  </ul>\n  \n  <p>If an int can represent all values of the original type,\n  the value is converted to an <code>int</code>;\n  otherwise, it is converted to an <code>unsigned int</code>.</p>\n</blockquote>\n\n<p>So, your test program should output the size of an <code>int</code>, i.e.,\n<code>sizeof(int)</code>.</p>\n\n<p>Is there any compiler that does not to this?</p>\n'}, {'answer_id': 84202, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': "<p>CL, I've seen your citations before, and agree they're totally relevant, but even after having read them I wasn't sure whether the code is defined.</p>\n\n<blockquote>\n  <p>6.3.1.1.2 says regarding integer promotions:</p>\n</blockquote>\n\n<p>Yes, but integer promotion rules only apply if a promotion is in fact carried out. I do not think that my example requires a promotion. Likewise if you do</p>\n\n<pre><code>char ch;\nsizeof ch;\n</code></pre>\n\n<p>... then ch also isn't promoted.</p>\n\n<p>I think we are dealing directly with the bitfield type here.</p>\n\n<p>I've also seen gcc output 1 while many other compilers (and even other gcc versions) don't. This doesn't convince me that the code is <strong>illegal</strong> because the size could just as well be implementation-defined enough to make the result inconsistent across multiple compilers.</p>\n\n<p>However, I'm confused as to whether the code may be undefined because nothing in the standard seems to state how the sizeof bitfield case is handled.</p>\n"}, {'answer_id': 84361, 'author': 'CL.', 'author_id': 11654, 'author_profile': 'https://Stackoverflow.com/users/11654', 'pm_score': 3, 'selected': True, 'text': '<p>You are right, integer promotions aren\'t applied to the operand of <code>sizeof</code>:</p>\n\n<blockquote>\n  <p>The integer promotions are applied only: as part of the usual arithmetic conversions, to certain argument expressions, to the operands of the unary +, -, and ~ operators, and to both operands of the shift operators, as specified by their respective subclauses.</p>\n</blockquote>\n\n<p>The real question is whether bitfields have their own types.</p>\n\n<p>Joseph Myers told me:</p>\n\n<blockquote>\n  <p>The conclusion\n  from C90 DRs was that bit-fields have their own types, and from C99 DRs \n  was to leave whether they have their own types implementation-defined, and \n  GCC follows the C90 DRs and so the assignment has type int:1 and is not \n  promoted as an operand of sizeof.</p>\n</blockquote>\n\n<p>This was discussed in <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_315.htm" rel="nofollow noreferrer">Defect Report #315</a>.</p>\n\n<p>To summarize: your code is legal but implementation-defined.</p>\n'}]
['https://Stackoverflow.com/questions/81294', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/-1/']