'Pragma pack (push, 1)' crashes in GCC 4.4.7. Possible compiler error?

I ran into a bug that puzzled me. I narrowed this down to a problem with the team pragma packin GCC (in particular, RHEL Linux, GCC v.4.4.7), which can be recreated in the small example that I showed below. It seems that GCC is calculating the wrong offset in this case, which will appear as a failure in the loop. Removing the pragma package also fixes the problem, but in a real application this leads to additional use of a gigabyte of memory and is undesirable.

In the example below, you need to compile with optimization enabled (O3) in order to experience a crash. I also introduced an example element (cMagic) in the structure that can be removed, which will alter the alignment of the structure and prevent the error from triggering.

I looked at the generated assembly and believe that this may be a compiler error. Am I missing something? Can anyone confirm this error or provide any ideas?

Crash.cpp:

/*  Platform Version Info:
 *     gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
 *     uname: 2.6.32-504.16.2.el6.x86_64 #1 SMP Tue Mar 10 17:01:00 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux
 *
 *  Compiling:
 *     Must use -O3 for compiling and linking
 *     CXX= g++ -g -O3 -fPIC -rdynamic -Wall -Wno-deprecated -DDEBUG
 *     CPP= g++ -g -O3 -fPIC -rdynamic -Wall -Wno-deprecated -DDEBUG
 *
 *  Notes:
 *     This appears to be an optimization and alignment issue.
 *     Getting rid of a byte in Place (cMagic) causes the program to complete successfully.
 *
 */


#include <stdlib.h>
#include <iostream>

using namespace std;

#pragma pack(push,1)  // Structures must be packed tightly
#define MAGICCONSTANT 17

struct Place {
   int iFoo;
   char cMagic;         // GCC doesn't like cMagic.  Disillusion it and everything is OK
   int aiArray[MAGICCONSTANT];
};


#pragma pack(pop)

int main(int argc, const char *argv[])
{
   Place *pPlace = new Place;   // Place must be on the heap... so new, calloc, malloc, etc

   for (int c = 0; (c < MAGICCONSTANT); c++) {
      pPlace->aiArray[c] = 0;
   }

   delete pPlace;

   cout << "Complete!" << endl;
   return 0;
}

Makefile:

CXX= g++ -g -O3 -fPIC -rdynamic -Wall -Wno-deprecated -DDEBUG
CPP= g++ -g -O3 -fPIC -rdynamic -Wall -Wno-deprecated -DDEBUG

OBJS=   Crash.o
SRCS=   Crash.cpp
TARG=   crash

debug:: ${TARG}

all:: ${TARG}

${TARG}: ${OBJS}
        ${CPP} -o ${TARG} ${OBJS} ${LDFLAGS} ${LIBS}

clean::
        rm -f ${TARG} ${OBJS} ${TARG}.core core

Disassembly schedule (generated ASM code):

Disassembly graph

+4
source share
1 answer

Look at using __attribute__ ((packed));instead #pragma pack(1). IIRC, this version of GCC treats this a little differently.

+4
source

All Articles