The Future Is Now

Attack the Vector

One downside of working with ancient OSs is coming across bugs that will never be fixed.

In the early days of Tigerbrew, I had just started experimenting with GCC 4.2 as a replacement for Xcode 2.5’s GCC 4.0. Everything was going great until I built something that uses Cocoa, which blew up with this message:

1
2
3
4
5
In file included from /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/DriverServices.h:32,
                 from /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/CarbonCore.h:125,
                 from /System/Library/Frameworks/CoreServices.framework/Headers/CoreServices.h:21,
                 from test.c:2:
/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MachineExceptions.h:115: error: expected specifier-qualifier-list before ‘vector’

A syntax error coming not from within the package I was building, but from within… Carbon?

The error actually comes from the Vector128 union within MachineExceptions.h, located in CoreServices’s CarbonCore framework. The very first section of this union had the offending code. Let’s play spot the bug:

Here’s what it looks like as of OS X 10.4.11:

1
2
3
4
5
6
7
8
9
typedef struct FPUInformationPowerPC    FPUInformationPowerPC;
union Vector128 {
#ifdef __VEC__
 vector unsigned int         v;
#endif
  unsigned long       l[4];
  unsigned short      s[8];
  unsigned char       c[16];
};

And here it is in OS X 10.7.51:

1
2
3
4
5
6
7
8
9
typedef struct FPUInformationPowerPC    FPUInformationPowerPC;
union Vector128 {
#ifdef __APPLE_ALTIVEC__
   vector unsigned int         v;
#endif
  unsigned long       l[4];
  unsigned short      s[8];
  unsigned char       c[16];
};

The bug comes from the use of the vector keyword. As pointed out in this MacPorts ticket, the issue is with the #ifdef that checks for __VEC__. __VEC__ is defined if AltiVec is on, without necessarily meaning that AltiVec syntactic extensions are enabled. The vector keyword is only available if either altivec.h is included, or the -mpim-altivec or -faltivec flags are passed. Since Tigerbrew always optimizes for the host CPU, G4 and G5 users were getting AltiVec enabled without forcing syntactic extensions. I fixed this in Tigerbrew this by always passing -faltivec on PowerPC systems when building any package, regardless of whether AltiVec is being used.

As to why Apple never caught this, GCC 4.0’s behaviour seems to be different; it seems to enable AltiVec syntactic extensions whenever -maltivec is on. Apple did eventually fix the bug, as seen in the Lion header above. According to the MacPorts ticket linked previously, it was fixed in the CarbonCore header in 10.5 and in the 10.4u SDK packaged in Xcode 3 for Leopard. Since the 10.4u SDK fix was never backported to Tiger itself, Tiger users have to make do with the workaround.


  1. 10.7 may be Intel-only, but the relevant code’s still there. In fact, the same PowerPC unions and structs are still there as of 10.9.4.