Go Down

Topic: __attribute__((packed)) is failing in Arduino 1.5.2 IDE (On Due board) (Read 758 times) previous topic - next topic

haturi

Hi,
After spending a day trying to debug a problem I narrowed it down to a 7-byte packed structure that the IDE is compiling as 8 bytes.

Here is a simplified sketch to reproduce the problem:-

Code: [Select]

void setup() {
  // put your setup code here, to run once:
typedef struct quest_st
{
    uint32_t    kern;
    uint8_t     chCount;

    union
    {
        uint8_t asAmpli;
        struct
        {
            uint8_t dir   : 4;
            uint8_t curve : 4;
        };
    } uAmpli;

    union
    {
        uint8_t asForce;
        struct
        {
            uint8_t amount  : 5;
            uint8_t axis    : 3;
        };
    } uForce;
   
}   QUEST  __attribute__((packed));

int  ss;
QUEST myQuest;
char buf[ 80];
 
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  Serial.println("Program start.");
  delay(200);

  if( &ss != NULL)
    ss = sizeof( QUEST);
  sprintf( &buf[0], "\n sizeof( QUEST) = %ld  sizeof(myQuest) = %ld"
    "  sizeof( struct quest_st) = %ld", ss, sizeof( myQuest), sizeof( struct quest_st));
  Serial.println( &buf[0]); 
}

void loop() {
  // put your main code here, to run repeatedly:
}


The IDE installed tree has not been changed in any way ...I am using the same version of the compiler that came with it originally in 1.5.2 release.
There is no warning of ignored attribute command (which I get in gcc on Fedora).

Is there a way to make that sizeof() operator behave correctly?  May be with some compiler flags?

Thanks.

Palliser

Hello haturi,
I think you are facing a syntax issue. Here the corrected code:

Code: [Select]
void setup() {
  // put your setup code here, to run once:
typedef struct __attribute__((packed)) quest_st
{
    uint32_t    kern;
    uint8_t     chCount;

    union
    {
        uint8_t asAmpli;
        struct
        {
            uint8_t dir   : 4;
            uint8_t curve : 4;
        };
    } uAmpli;

    union
    {
        uint8_t asForce;
        struct
        {
            uint8_t amount  : 5;
            uint8_t axis    : 3;
        };
    } uForce;
   
}   QUEST;

int  ss;
QUEST myQuest;
char buf[ 80];
 
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  Serial.println("Program start.");
  delay(200);

  if( &ss != NULL)
    ss = sizeof( QUEST);
  sprintf( &buf[0], "\n sizeof( QUEST) = %ld  sizeof(myQuest) = %ld"
    "  sizeof( struct quest_st) = %ld", ss, sizeof( myQuest), sizeof( struct quest_st));
  Serial.println( &buf[0]); 
}

void loop() {
  // put your main code here, to run repeatedly:
}


Output:
Quote
Program start.

sizeof( QUEST) = 7  sizeof(myQuest) = 7  sizeof( struct quest_st) = 7


Regards!

haturi

Thanks Palliser.  No doubt that will solve my problem! :)
I wonder why the compiler went silent about such a major decision!

Palliser

Yep. Compilation without complaints. I know what that means. I also do not imagine myself crafting my code with asserts trying to catch layout errors only because my program misbehaves at run time. It's like chasing the white rabbit. That has been always the thing with C/C++ compilers. They are like old blind and mute Lamas to whom we must be attentive, in silence, waiting for any sign like: error 0x45AC00000 ITIPHHTEMETEIROEBE. Regards! 

Go Up