Strict aliasing errors

From: Orion Poplawski <orion_at_nyahnyahspammersnyahnyah>
Date: Fri Jul 13 2012 - 10:13:56 MDT

Compiling ncl 6.0.0 on Fedora yields the following strict-aliasing warnings,
which can lead to unexpected code behavior:

NclCCM.c:312:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:320:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:326:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:347:2: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:351:2: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:724:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:725:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:729:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:312:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:320:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:326:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:347:2: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:351:2: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:724:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:725:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
NclCCM.c:729:3: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]

comes from (int *) casts:
static int extractCCM(int which,char buf[8])
{
         char tmp[8];

         switch(which){
         case 0:
                 return((int)buf[0]>>4);
         case 1:
                 tmp[BYTE0] = 0;
                 tmp[BYTE1] = (buf[0]<<4)>>4;
                 tmp[BYTE2] = buf[1];
                 tmp[BYTE3] = buf[2];
                 return(*(int*)tmp);
         case 2:
                 return((int)buf[3]>>7);
         case 3:
                 tmp[BYTE0] = 0;
                 tmp[BYTE1] = buf[4]>>1;
                 tmp[BYTE2] = buf[5]>>1 | (buf[4]&(char)0001)<<7;
                 tmp[BYTE3] = buf[6]>>1 | (buf[5]&(char)0001)<<7;
                 return(*(int*)tmp);
         case 4:
                 tmp[BYTE0] = 0;
                 tmp[BYTE1] = 0;
                 tmp[BYTE2] = buf[6] & (char)0001;
                 tmp[BYTE3] = buf[7];
                 return(*(int*)tmp);
         }

BuiltInFuncs.c:3110:4: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
BuiltInFuncs.c:3119:4: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
BuiltInFuncs.c:3263:5: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
BuiltInFuncs.c:3275:5: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
BuiltInFuncs.c:3464:4: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
BuiltInFuncs.c:3480:4: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
BuiltInFuncs.c:3501:4: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]

 From statements like:
                         ind1 = *(int*)control_word;

craybin.c:112:17: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
craybin.c:120:17: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]
craybin.c:126:17: warning: dereferencing type-punned pointer will break
strict-aliasing rules [-Wstrict-aliasing]

Comes from the (int*) casts:
static int extract(int which,char buf[8])
{
         char tmp[8];

         switch(which){
         case 0:
                 return((int)buf[0]>>4);
         case 1:
                 tmp[BYTE0] = 0;
                 tmp[BYTE1] = (buf[0]<<4)>>4;
                 tmp[BYTE2] = buf[1];
                 tmp[BYTE3] = buf[2];
                 return(*(int*)tmp);
         case 2:
                 return((int)buf[3]>>7);
         case 3:
                 tmp[BYTE0] = 0;
                 tmp[BYTE1] = buf[4]>>1;
                 tmp[BYTE2] = buf[5]>>1 | (buf[4]&(char)0001)<<7;
                 tmp[BYTE3] = buf[6]>>1 | (buf[5]&(char)0001)<<7;
                 return(*(int*)tmp);
         case 4:
                 tmp[BYTE0] = 0;
                 tmp[BYTE1] = 0;
                 tmp[BYTE2] = buf[6] & (char)0001;
                 tmp[BYTE3] = buf[7];
                 return(*(int*)tmp);
         }
         return 0;
}

These seem to arise from trying to convert arrays of character's into integers
by casting them from (char *) to (int *), which while seemingly
straightforward does not conform to modern C standard requirements so there is
really no guarantee that it will do what you expect. Probably better to
construct the integer explicitly from the component bytes.

-- 
Orion Poplawski
Technical Manager                     303-415-9701 x222
NWRA, Boulder Office                  FAX: 303-415-9702
3380 Mitchell Lane                       orion@nwra.com
Boulder, CO 80301                   http://www.nwra.com
_______________________________________________
ncl-talk mailing list
List instructions, subscriber options, unsubscribe:
http://mailman.ucar.edu/mailman/listinfo/ncl-talk
Received on Fri Jul 13 10:14:07 2012

This archive was generated by hypermail 2.1.8 : Wed Jul 18 2012 - 14:33:00 MDT