Menu

#682 Ignore __attribute__((__packed__)) instead of throwing error

None
closed-fixed
None
5
2022-11-15
2020-06-30
Tim B.
No

Other compilers, such as AVR-GCC, require adding "__attribute__((__packed__))" bitfield struct definitions to signal that compiler that the struct should be combined in one data word (e.g. a byte).
SDCC does not require adding this attribute because it automatically infers that the bitfield is to be packed.

However, instead, an error is thrown when this attribute is encountered. For better compatibility to other compilers, I would suggest to ignore this attribute for now, so no code changes are needed when code is transferred between compilers.

struct PORT_bits
{
    uint8_t p0:1;
    uint8_t p1:1;
    uint8_t p2:1;
    uint8_t p3:1;
    uint8_t p4:1;
    uint8_t p5:1;
    uint8_t p6:1;
    uint8_t p7:1;
} __attribute__((__packed__));

Related

Wiki: SDCC-STD-UX

Discussion

  • Philipp Klaus Krause

    The above struct example does not require any attribute. When the byte boundaries fall on bit-field boundaries, no internal padding is added:
    "An implementation may allocate any addressable storage unit large enough to hold a bit-field. If
    enough space remains, a bit-field that immediately follows another bit-field in a structure shall be
    packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that
    does not fit is put into the next unit or overlaps adjacent units is implementation-defined." (from the C2X standard draft N2479, but AFAIK this has been the same since ASI C89).

    AFAIK, SDCC, at least for mostbackends, does not support packing for cases where a bit-field spans multiple bytes with both boundaries not on byte boundaries, e.g.

    struct
    {
        int i : 4;
        int j : 8;
    } s;
    

    will have padding bits in between i and j, so ignoring a __attribute(packed)__ would be misleading.
    Also, I wonder if it really makes sense to support that legacy attribute syntax (SDCC already has some support for C2X attributes using the [[ ]] syntax).

     

    Last edit: Philipp Klaus Krause 2020-06-30
  • Maarten Brock

    Maarten Brock - 2020-06-30
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,4 +1,4 @@
    -Other compilers, such as AVR-GCC, require adding "__attribute__((__packed__))" bitfield struct definitions to signal that compiler that the struct should be combined in one data word (e.g. a byte). 
    +Other compilers, such as AVR-GCC, require adding "\_\_attribute\_\_((\_\_packed\_\_))" bitfield struct definitions to signal that compiler that the struct should be combined in one data word (e.g. a byte). 
     SDCC does not require adding this attribute because it automatically infers that the bitfield is to be packed.
    
     However, instead, an error is thrown when this attribute is encountered. For better compatibility to other compilers, I would suggest to ignore this attribute for now, so no code changes are needed when code is transferred between compilers.
    
    • Group: -->
     
  • Maarten Brock

    Maarten Brock - 2020-06-30

    Furthermore, a simple macro definition can fix this problem.

     
  • Benedikt Freisen

    I've been using -D__attribute__(a)= on the command line for a while.
    It works as intended, i.e. discards all such attributes via preprocessor.
    The motivation was the same, namely to be able to use unmodified source files.

     
  • Benedikt Freisen

    If you want to translate GCC-style attribute syntax to C2X attribute syntax, the preprocessor can do that, too.
    After a bit of stackoverflow research I came up with this preprocessor macro monstrosity:

    #define __ATTR_SYNTAX_HELPER_LIST_ARGS(...) __VA_ARGS__
    #define __ATTR_SYNTAX_HELPER_UNWRAP_ARG(__ATTR_SYNTAX_HELPER_ARG) __ATTR_SYNTAX_HELPER_ARG
    #define __attribute__(__ATTR_SYNTAX_HELPER_ARG) [[__ATTR_SYNTAX_HELPER_UNWRAP_ARG(__ATTR_SYNTAX_HELPER_LIST_ARGS __ATTR_SYNTAX_HELPER_ARG)]]
    

    It will happily transform something like __attribute__((packed, foo(bar))) into [[packed, foo(bar)]].

    You could put it in a file named e.g. attr_syntax_helper.h and include it via -Wp -include,attr_syntax_helper.h.

     
    • Philipp Klaus Krause

      That should work for most use-cases.

      AFAIK, there are a few exceptions, where GCC attributes can be placed in a location different from the C23 attributes, though (I think in function declarations, GCC attributes that actually apply to the function type can be placed as if they'd apply to the declaration instead of the type).

      P.S.: Interestingly, this difference in attribute placement means that the standard attribute placement works like the current SDCC "attribute" placement for stuff like __z88dk_fastcall, __naked etc, while the GCC attributes can also be placed in the location where the non-free competition (IAR, Cosmic, Raisonance, etc) place them.

       

      Last edit: Philipp Klaus Krause 2022-03-09
    • Benedikt Freisen

      Starting with [r13239], this style of conversion is provided in gcc_attr.h, which can either be included normally or via --include gcc_attr.h on the command line.

       

      Related

      Commit: [r13239]

  • Philipp Klaus Krause

    I'd assume that that the GCC syntax will quickly die out. Now that we have the C23 attribute syntax approved by SC22 WG14, which is also the same syntax C++ uses.

     
  • Benedikt Freisen

    • status: open --> closed-fixed
    • assigned_to: Benedikt Freisen
     
  • Benedikt Freisen

    Implemented using preprocessor magic:

    Use --include gcc_attr.h to pre-include a helper header that translates the GCC syntax to C23 syntax when in C23 mode and discards all attributes, otherwise.

     

Log in to post a comment.

MongoDB Logo MongoDB