Bug 60972 - Mixing #pragma pack and __attribute__((packed)) leads to spurious warnings.
Summary: Mixing #pragma pack and __attribute__((packed)) leads to spurious warnings.
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: 44209
  Show dependency treegraph
 
Reported: 2014-04-26 01:23 UTC by John Steele Scott
Modified: 2025-04-02 18:42 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-08-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John Steele Scott 2014-04-26 01:23:51 UTC
┌(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.
Comment 1 Eric Gallager 2017-08-23 20:13:08 UTC
Confirmed. Another problem with the warnings is that there's no flag controlling them. I'd expect one of -Wno-packed, -Wno-attributes, or -Wno-ignored-attributes to disable the warning, but none of them do so.
Comment 2 Eric Gallager 2019-03-11 18:50:57 UTC
cc-ing C++ FE maintainers
Comment 3 Eric Gallager 2019-06-11 05:58:38 UTC
(In reply to Eric Gallager from comment #1)
> Confirmed. Another problem with the warnings is that there's no flag
> controlling them. I'd expect one of -Wno-packed, -Wno-attributes, or
> -Wno-ignored-attributes to disable the warning, but none of them do so.

That part makes this fall under bug 44209
Comment 4 GCC Commits 2025-04-02 18:37:26 UTC
The master branch has been updated by Sandra Loosemore <sandra@gcc.gnu.org>:

https://gcc.gnu.org/g:a2e03736fc932ef613ad01a9499126cbaa538bf8

commit r15-9155-ga2e03736fc932ef613ad01a9499126cbaa538bf8
Author: Sandra Loosemore <sloosemore@baylibre.com>
Date:   Wed Apr 2 18:20:35 2025 +0000

    Doc: #pragma pack documentation cleanup [PR114957] [PR78008] [PR60972]
    
    This patch addresses a number of issues with the documentation of
    
    - None of the things in this section had @cindex entries [PR114957].
    
    - The document formatting didn't match that of other #pragma
    documentation sections.
    
    - The effect of #pragma pack(0) wasn't documented [PR78008].
    
    - There's a long-standing bug [PR60972] reporting that #pragma pack
    and the __attribute__(packed) don't get along well.  It seems worthwhile
    to warn users about that since elsewhere pragmas are cross-referenced
    with related or equivalent attributes.
    
    gcc/ChangeLog
            PR c/114957
            PR c/78008
            PR c++/60972
            * doc/extend.texi (Structure-Layout Pragmas):  Add @cindex
            entries and reformat the pragma descriptions to match the markup
            used for other pragmas.  Document what #pragma pack(0) does.
            Add cross-references to similar attributes.
Comment 5 sandra 2025-04-02 18:42:54 UTC
I've updated the manual to document that this doesn't work, and say "don't do that".  However, the actual bug is not fixed.  If anyone ever does so, please address the FIXME in extend.texi.