tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Weird bitfield size handling, discrepancy with gcc


From: Vincent Lefevre
Subject: Re: [Tinycc-devel] Weird bitfield size handling, discrepancy with gcc
Date: Tue, 18 Oct 2016 09:41:49 +0200
User-agent: Mutt/1.7.1-6816-vl-r91193 (2016-10-12)

On 2016-10-18 06:57:09 +0200, Christian Jullien wrote:
> Hi all,
> VC++ 32 and 64 both return:
> t1 struct size: 2
> t2 struct size: 8
> t3 struct size: 8
> 
> Which IMHO is correct. I really don’t understand why gcc returns
> t1 struct size: 2
> t2 struct size: 4
> t3 struct size: 4

AFAIK, both are correct.

> To me,
> struct t2 {
>     uint32_t op_type:1;
>     uint8_t op_flags;
> };
> 
> op_type uses a plain uint32_t to store only one bit as there is
> another field which is not a bit bitfield, C compile must allocate
> at least one extra byte in this struct. The minimal size I expect
> is 5!

I disagree. For the bit-field, a size 1 is sufficient for 1 bit.
So, the minimum size of the structure I would expect is 2 in all
of the 3 examples. Actually, even though the standard does not
require this, I would have expected the same size for all of these
3 examples, as this would have been more consistent, unless the
type of the bit-field is regarded as a hint for alignment choices.

> I changed you sample a little bit to see offset of op_flags:
> 
> #include <stdint.h>
> #include <stdio.h>
> #include <stddef.h>
> struct t1 {
>     uint8_t op_type:1;
>     uint8_t op_flags;
> };
> struct t2 {
>     uint32_t op_type:1;
>     uint8_t op_flags;
> };
> struct t3 {
>     unsigned op_type:1;
>     char op_flags;
> };
> 
> int main() {
>     printf("t1 struct size: %ld\n", sizeof(struct t1));
>     printf("t2 struct size: %ld\n", sizeof(struct t2));
>     printf("t2 offset of op_flags: %ld\n", offsetof(struct t2, op_flags));
>     printf("t3 struct size: %ld\n", sizeof(struct t3));
>     return 0;
> }
> 
> Visual C++ gives:
> t1 struct size: 2
> t2 struct size: 8
> t2 offset of op_flags: 4
> t3 struct size: 8
> 
> While gcc gives
> c:\tmp>a.exe
> t1 struct size: 2
> t2 struct size: 4
> t2 offset of op_flags: 1
> t3 struct size: 4
> 
> Which IMHO is wrong. If later I change my mind with:
> struct t2 {
>     uint32_t op_type:1;
>     uint32_t op_other_field: 12;
>     uint8_t op_flags;
> };

I see GCC's choice as OK. If you change your mind, the structure
changes and the offset of op_flags may change. I don't see anything
wrong here.

> I expect my struct will have the same size.

Different users have different expectations. For instance, I would
have expected the same size for the initial 3 examples. But as long
as the standard doesn't specify anything, the entire choices are
left to the implementation.

> I don't think we want tcc mimic this behavior. Doing this will break
> Windows code that depends on this behavior. The only solution is to
> add a compiler flag to ask for a specific behavior.

There are at least 2 things that should be specified: how offsets are
determined (i.e. how the unit sizes are determined), and how alignment
(which affects the size of the structure) is determined.

-- 
Vincent Lefèvre <address@hidden> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]