[Bug c++/36566] Cannot bind packed field

2021-12-31 Thread steve+gcc at tecwec dot eu via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

Eric Estievenart  changed:

   What|Removed |Added

 CC||steve+gcc at tecwec dot eu

--- Comment #14 from Eric Estievenart  ---
What about:
struct S
{
int i;
}  __attribute__((__packed__)) __attribute((aligned(8)));

void f( S* s )
{
int& i = s->i; // Error here
}

S::i is obviously properly aligned, the compiler should know it and accept the
referencing.

As for the argument 'the field might be unaligned and this would violate... and
crash...', I don´t really agree. The compiler knows the arch, the alignment,
and it can decide:
- to emit an error if unaligned(or unknown) if alignment required by arch
- to emit a warning on other arch

Note by the way that this seems accepted by clang...

[Bug c++/36566] Cannot bind packed field

2020-03-04 Thread rene.r...@fu-berlin.de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

--- Comment #13 from Rene Rahn  ---
(In reply to Eric Gallager from comment #12)
> (In reply to Rene Rahn from comment #10)
> > I know this is quite old now. But can someone explain me why using `#pragma
> > pack(push, 1)` does work then? I couldn't find enough resources on that. The
> > only thing I found is, that it does literally the same. But wouldn't then
> > the references/pointers still not be valid?
> > 
> > So if I change the code to:
> > 
> > ```
> > #pragma pack(push, 1)
> > struct Squeeze
> > {
> > short   s;
> > };
> > #pragma pack(pop)
> > ```
> > 
> > Then it works on godbolt with gcc-trunk.
> 
> There are several bugs open about inconsistencies between
> __attribute__((packed)) and #pragma pack; see for example: bug 93910, bug
> 92900, bug 68160, and bug 60972

Ah great. Thanks for pointing to this.

[Bug c++/36566] Cannot bind packed field

2020-03-04 Thread egallager at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

Eric Gallager  changed:

   What|Removed |Added

 CC||egallager at gcc dot gnu.org
   See Also||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=93910,
   ||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=92900,
   ||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=68160,
   ||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=60972

--- Comment #12 from Eric Gallager  ---
(In reply to Rene Rahn from comment #10)
> I know this is quite old now. But can someone explain me why using `#pragma
> pack(push, 1)` does work then? I couldn't find enough resources on that. The
> only thing I found is, that it does literally the same. But wouldn't then
> the references/pointers still not be valid?
> 
> So if I change the code to:
> 
> ```
> #pragma pack(push, 1)
> struct Squeeze
> {
> short   s;
> };
> #pragma pack(pop)
> ```
> 
> Then it works on godbolt with gcc-trunk.

There are several bugs open about inconsistencies between
__attribute__((packed)) and #pragma pack; see for example: bug 93910, bug
92900, bug 68160, and bug 60972

[Bug c++/36566] Cannot bind packed field

2020-03-03 Thread ed at catmur dot uk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

--- Comment #11 from Ed Catmur  ---
(In reply to rene.rahn from comment #10)
> I know this is quite old now. But can someone explain me why using `#pragma
> pack(push, 1)` does work then? 

`#pragma pack` has sharper edges. It will let you take unaligned
pointers/references, but they will break on architectures that enforce
alignment or under ubsan, and the compiler won't try to save you. This is for
compatibility with other (older) compilers that behave similarly.

nb.

Since 4.7 `short& pit(oj.s);` gives error: cannot bind packed field
'oj.Squeeze::s' to 'short int&' (comment #1).

Since 9.1 `short* ppit();` and `VerticallyChallenged();` give
warning: taking address of packed member of 'Squeeze' may result in an
unaligned pointer value [-Waddress-of-packed-member] (comment #3).

And the typedef `using un_short = short __attribute__((aligned(1)));` (comment
#6) gives a way to form references and pointers to these fields and pass them
around. (Note that you have to cast the field access at point of use.)

So I think this can be RESOLVED FIXED version 9.1.

[Bug c++/36566] Cannot bind packed field

2020-03-03 Thread rene.r...@fu-berlin.de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

rene.r...@fu-berlin.de changed:

   What|Removed |Added

 CC||rene.r...@fu-berlin.de

--- Comment #10 from rene.r...@fu-berlin.de ---
I know this is quite old now. But can someone explain me why using `#pragma
pack(push, 1)` does work then? I couldn't find enough resources on that. The
only thing I found is, that it does literally the same. But wouldn't then the
references/pointers still not be valid?

So if I change the code to:

```
#pragma pack(push, 1)
struct Squeeze
{
short   s;
};
#pragma pack(pop)
```

Then it works on godbolt with gcc-trunk.

[Bug c++/36566] Cannot bind packed field

2017-02-11 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

--- Comment #9 from Marc Glisse  ---
I was thinking that
struct __attribute__((packed)) A { int i; };
should be handled like
typedef int int_unaligned __attribute__((aligned(1)));
struct A { int_unaligned i; };
but it appears that for the aligned attribute as well we ignore the attribute
when forming pointers or references. Depending on the uses, the compiler can
print things like "int_unaligned* {aka int*}" or "ignoring attributes on
template argument" etc. It seems to me that we should not drop the
alignment-reducing attribute in those cases (it is still fine to remove it when
deducing a pass-by-copy type, as in templatevoid f(T);int_unaligned i;
f(i); which could safely deduce T=int. Return types may be more tricky when
they end up passed as invisible reference). The C/C++ standard only consider
_Alignas/alignas to increase alignment, so I don't think changes to the case
that decreases alignment would be a conformance issue.

[Bug c++/36566] Cannot bind packed field

2015-03-17 Thread redi at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

--- Comment #8 from Jonathan Wakely redi at gcc dot gnu.org ---
(In reply to Xiao Jia from comment #7)
 Adding const makes it compile.  Is this the intended behavior or not?

Yes, of course. A const-reference causes a temporary to be created, you didn't
bind to the packed field:

Squeeze oj;
oj.s = 0;
const short pit(oj.s);
oj.s = 1;
printf(%d %d, oj.s, pit);

This shows that oj.s and pit are not the same variable.


[Bug c++/36566] Cannot bind packed field

2015-03-17 Thread xiaoj at google dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

Xiao Jia xiaoj at google dot com changed:

   What|Removed |Added

 CC||xiaoj at google dot com

--- Comment #7 from Xiao Jia xiaoj at google dot com ---
What is the status of this?

Adding const makes it compile.  Is this the intended behavior or not?


struct Squeeze
{
short   s;
} __attribute__((aligned(1), packed));

void VerticallyChallenged(const short) {}

int main()
{
Squeeze oj;
const short pit(oj.s);
VerticallyChallenged(pit);
VerticallyChallenged(oj.s);
}


[Bug c++/36566] Cannot bind packed field

2013-09-14 Thread gabriel at teuton dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

--- Comment #6 from Gabriel M. Beddingfield gabriel at teuton dot org ---
All assignments of obj.s to type short and short* are incorrect, and ideally
they would all result in compiler errors.

The C++ spec (C++03, Sects. 3.9, 3.9.1, 3.9.2) are very clear that T and
pointer to T have implementation-specific alignment requirements.  If you
have a pointer to T then you may assume that it meets the alignment
requirements.  I'm sure the C spec has similar language.

In the OP's case, the following code could violate the alignment requirements:

short pit(obj.s); /* invalid */

For example obj.s could have an address 0x602011 (which has 1-byte
alignement).  When you assign that pointer to pit... pit is now a reference
(i.e. pointer) that violates the alignment requirements of short (which usually
requires 2-byte alignment).

Why is this a problem?  On x86/x86_64 it's *usually* no big deal because the
CPU will gracefully handle unaligned memory access (with a performance
penalty).  On less forgiving hardware platforms, trying to use `pit' will
result in illegal instruction exceptions.

You can pass the reference if you change the function prototype to something
like:

typedef short un_short __attribute__((alignment(1)));
void VerticallyChallenged(un_short) {}

...and then call it with a cast like this:

VerticallyChallenged((un_short)oj.s);

[amazing, the kind of stuff you learn over the course of 4 years :-)]


[Bug c++/36566] Cannot bind packed field

2013-09-12 Thread structurechart at yahoo dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

Hei structurechart at yahoo dot com changed:

   What|Removed |Added

 CC||structurechart at yahoo dot com

--- Comment #5 from Hei structurechart at yahoo dot com ---
any update on this? I run into the same issue with gcc 4.6.x


[Bug c++/36566] Cannot bind packed field

2009-10-10 Thread gabriel at teuton dot org


--- Comment #4 from gabriel at teuton dot org  2009-10-11 04:38 ---
I have the same problem with g++ 4.2.4 and 4.3.2.


-- 

gabriel at teuton dot org changed:

   What|Removed |Added

 CC||gabriel at teuton dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566



[Bug c++/36566] Cannot bind packed field

2008-06-18 Thread pinskia at gcc dot gnu dot org


--- Comment #1 from pinskia at gcc dot gnu dot org  2008-06-18 18:31 ---
This is correct you cannot take the address of a field of a packed struct.

short pit(oj.s);

This should be also an error.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566



[Bug c++/36566] Cannot bind packed field

2008-06-18 Thread nevin at eviloverlord dot com


--- Comment #2 from nevin at eviloverlord dot com  2008-06-18 18:49 ---
Why is this an error (I couldn't find anything in the documentation)?

Also, if pointers are used instead of references, should that be an error
(currently that compiles just fine)?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566



[Bug c++/36566] Cannot bind packed field

2008-06-18 Thread nevin at eviloverlord dot com


--- Comment #3 from nevin at eviloverlord dot com  2008-06-18 19:06 ---
Expanding on my last comment:  which lines in the following code should fail to
compile:

struct Squeeze
{
short   s;
} __attribute__((aligned(1), packed));

void VerticallyChallenged(short*) {}
void VerticallyChallenged(short) {}

int main()
{
Squeeze oj;
short pit(oj.s);
short* ppit(oj.s);

VerticallyChallenged(ppit); // okay
VerticallyChallenged(oj.s);// okay

VerticallyChallenged(pit);  // okay
VerticallyChallenged(oj.s); // cannot bind packed field ‘oj.Squeeze::s’
to ‘short int’
}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566