[Bug c++/60972] New: Mixing #pragma pack and __attribute__((packed)) leads to spurious warnings.
toojays at toojays dot net
gcc-bugzilla@gcc.gnu.org
Sat Apr 26 01:23:00 GMT 2014
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60972
Bug ID: 60972
Summary: Mixing #pragma pack and __attribute__((packed)) leads
to spurious warnings.
Product: gcc
Version: 4.9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: toojays at toojays dot net
┌(toojays@kano)─(568)─(0)─(2014 04 26 10:35:27)
└─(/tmp)─> /opt/gcc-4.9/bin/gcc --version | head -n1
gcc (GCC) 4.9.0
┌(toojays@kano)─(569)─(0)─(2014 04 26 10:35:35)
└─(/tmp)─> cat packed.cpp
#include <cstdint>
#include <type_traits>
#pragma pack(push, 1)
struct A
{
private:
uint16_t x;
uint32_t y;
public:
A () = default;
A (uint16_t x_, uint32_t y_) : x(x_), y(y_) {}
};
#pragma pack(pop)
struct __attribute__((packed)) B
{
A xx;
uint32_t yy;
A zz;
};
A a;
B b;
static_assert(std::is_pod<A>::value, "Expect A to be POD.");
static_assert(std::is_pod<B>::value, "Expect B to be POD.");
┌(toojays@kano)─(570)─(0)─(2014 04 26 10:35:46)
└─(/tmp)─> /opt/gcc-4.9/bin/gcc -std=c++11 -o packed.o -c packed.cpp -g
packed.cpp:22:5: warning: ignoring packed attribute because of unpacked non-POD
field ‘A B::xx’
A xx;
^
packed.cpp:26:5: warning: ignoring packed attribute because of unpacked non-POD
field ‘A B::zz’
A zz;
I have three problems with these warnings:
1) The warning claims that A is non-POD, but the type trait disagrees.
2) The warning claims that A is not-packed, but in fact it is.
3) Despite saying the attribute would be ignored, GCC went ahead and packed
struct B anyway. I am on amd64. If B is not packed then B::yy would be aligned
to a 4-byte boundary. Instead, the structures are packed, as shown:
┌(toojays@kano)─(571)─(0)─(2014 04 26 10:36:19)
└─(/tmp)─> pahole packed.o
die__process_class: tag not supported (template_type_parameter)!
die__process_class: tag not supported (template_value_parameter)!
struct A {
private:
uint16_t x; /* 0 2 */
uint32_t y; /* 2 4 */
void A(class A *);
void A(class A *, uint16_t, uint32_t);
/* size: 6, cachelines: 1, members: 2 */
/* last cacheline: 6 bytes */
};
struct B {
struct A xx; /* 0 6 */
uint32_t yy; /* 6 4 */
struct A zz; /* 10 6 */
void B(class B *);
/* size: 16, cachelines: 1, members: 3 */
/* last cacheline: 16 bytes */
};
If I consistently use #pragma or __attribute__ for both structures, GCC does
not complain, and my structures are packed as I would expect.
More information about the Gcc-bugs
mailing list