0

I'm modeling a LCD hitachi display parallel port connection (for those interested HD44780, in 4 bit mode).

Even though alignment is set to 1,this union still takes up 2 bytes. If I get rid of the msnibble struct (directly put db4 to db7 in the struct in the union) it takes up 1 byte. Can structs take up less than 1 byte if they're inside a union? Is the 2 bytes the result of the msnibble taking up 1 byte plus the nibble (the enable bit,rs bit and the two blank bits), thus making the size 2 bytes?

Here's the code:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint8_t byte_t;//could have used char

#pragma pack(push,1) 
typedef union
{
    byte_t  whole_port  :8;
    struct
    {
        byte_t enable       :1;
        byte_t rs           :1;
        byte_t              :1;
        byte_t              :1;
        struct 
        {
            byte_t db4          :1;
            byte_t db5          :1;
            byte_t db6          :1;
            byte_t db7          :1; 
        }msnibble;

    };
} para_port_t;
#pragma pack(pop)

int main(int argc, char** argv) {
    printf("%u\n",sizeof(para_port_t));
    return (EXIT_SUCCESS);
}

I'm working from netbeans in ubuntu compiling with gcc. As pragma is a compiler directive I wanted to know if it's the same in Microsoft Visual Studio?

halfer
  • 19,824
  • 17
  • 99
  • 186
Mr. Branch
  • 442
  • 2
  • 13
  • `typedef uint8_t byte_t; // could have used char` ~ could have used `unsigned char`. – Weather Vane May 25 '16 at 17:17
  • I think you are trying to do something stupid here: http://stackoverflow.com/q/11326460/1566187 – Ely May 25 '16 at 17:18
  • 1
    `Is the 2 bytes the result of the msnibble taking up 1 byte plus the nibble(the enable bit,rs bit and the two blank bits), thus making the size 2 bytes?` yes, I cannot refer to standard, but it looks like this internal struct uses additional byte – Iłya Bursov May 25 '16 at 17:24
  • 1
    Note: "A bit-field shall have a type that is a qualified or unqualified version of `_Bool, signed int, unsigned int`, or some other implementation-defined type. §6.7.2.1 Using a bit-field with `uint8_t` is implementation-defined behavior. A C compliant complier need not even compile this code. Suggest adding tags of the compiler/platforms of interest. – chux - Reinstate Monica May 25 '16 at 18:49
  • @Weather Vane for `uint8_t` to exist, `CHAR_BIT` must be 8 and so `typedef unsigned char byte_t;` provide no benefit yet risks incorrect operation when `CHAR_BIT > 8`. – chux - Reinstate Monica May 25 '16 at 18:53
  • I think the issue is that `msnibble` needs a computable byte offset, so it must begin on a `byte` boundary. So the anonymous `struct` is 2 bytes. – chux - Reinstate Monica May 25 '16 at 18:55
  • @chux re your quibble about the number of bits in a byte, my point was that `char` might be signed, but `uint8_t` is not, no matter how many bits. But the risk of 9 bits in a byte is typically small. – Weather Vane May 25 '16 at 18:59
  • @Weather Vane Agree OP's comment should have been `// could have used unsigned char`. I took [your comment](http://stackoverflow.com/questions/37443477/why-does-this-union-take-up-2-bytes-even-though-im-aligning-to-one?noredirect=1#comment62389762_37443477) to suggest `typedef unsigned char byte_t; `. – chux - Reinstate Monica May 25 '16 at 19:09
  • Are you asking why bit fields of both structs aren't joined into a single byte? – 2501 May 25 '16 at 20:22

2 Answers2

1

Your final question asks if MSVC has 2 bytes for the union: yes it does.

Your union has one variant as struct nested within struct. How could that be 1 byte? Without the union,

#pragma pack(push,1) 

typedef struct {
    byte_t enable       :1;
    byte_t rs           :1;
    byte_t              :1;
    byte_t              :1;
    struct 
    {
        byte_t db4          :1;
        byte_t db5          :1;
        byte_t db6          :1;
        byte_t db7          :1; 
    }msnibble;
} thatstruct;

#pragma pack(pop)

has a size of 2. Where does it say that nested structs can be packed into 1 byte?

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
-1

Can structs take up less than 1 byte if they're inside a union?

Nope. Your nested struct takes a full byte, and your outer struct rounds up to two bytes.