0

I have a C main file in which this .h file is included:

#pragma pack(1) 
 #ifndef PACKAGE
 #define PACKAGE


struct A {
  uint8_t a;
  uint8_t b;
  uint64_t c;

} typedef A;


#endif

After compiling the warning :

    myfile.c:28:10: warning: the current #pragma pack alignment value is modified in
      the included file [-Wpragma-pack]
#include "structures.h"
         ^
./structures.h:1:9: note: previous '#pragma pack' directive that modifies
      alignment is here
#pragma pack(1)

appears.

I don't understand what's wrong in my code. Is there any way to delete this warning ?

Here is a complete example :

This is a simple C file called "myfile.c" :

#include "structures.h"
int main(){
  return 0;
}

And this is the .h file called "structures.h" :

#include <stdlib.h>
#include <stdio.h>

  #pragma pack(1)
 #ifndef PACKAGE
 #define PACKAGE


struct A {
  uint8_t a;
  uint8_t b;
  uint64_t c;

} typedef A;


#endif

And the warning is :

myfile.c:2:10: warning: the current #pragma pack alignment value is modified in
      the included file [-Wpragma-pack]
#include "structures.h"
         ^
./structures.h:5:11: note: previous '#pragma pack' directive that modifies
      alignment is here
  #pragma pack(1)
          ^
1 warning generated.
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Julien
  • 91
  • 8

1 Answers1

5

Maybe you need to read the GCC manual on pragmas — §6.61.10 Structure-Layout Pragmas. You could sensibly use:

#ifndef PACKAGE
#define PACKAGE

#pragma pack(push, 1) 

typedef struct A {
  uint8_t a;
  uint8_t b;
  uint64_t c;
} A;

#pragma pack(pop) 

#endif /* PACKAGE */

I don't know whether this works with all the compilers that are relevant to you.

Incidentally, I moved the typedef keyword to the start. The C grammar treats typedef as a storage class, and also stipulates (C11 §6.11.5 Storage class specifiers) that the placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Put the keyword typedef first!

I also note that this header is not self-contained (though it is idempotent because of the header guards). It relies on <stdint.h> (or perhaps <inttypes.h>) having been included already. Ideally, you should add #include <stdint.h> before the first #pragma so that the code will compile even if this is the first header included in a translation unit. See also Should I use #include inside headers?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    Chuckling... just fixing the `typedef` allowed his original to compile on gcc. – David C. Rankin Apr 12 '19 at 23:46
  • 1
    @DavidC.Rankin — Hmmmm…that never occurred to me as a possibility. I've not sent the code past a compiler, neither the original nor my response. If moving the `typedef` around 'fixes' the original, then a wry chuckle of mild disbelief is in order. – Jonathan Leffler Apr 12 '19 at 23:49
  • I did move the other includes and `#pragma pack(1)` inside the `PACKAGE` header guard, but other than that, I ran it with `-Wall -Extra -pedantic` and gcc was happy with it. (also added a declaration `A a = { .a = 1, .b = 2, .c = 0xdeadbeef };` and `printf ("a.c 0x%" PRIx64 "\n", a.c);` just to make sure everything wasn't optimized out). gcc likes your solution equally well. – David C. Rankin Apr 12 '19 at 23:51