我正在创建一个使用Apple GLKit标头的应用程序。在此库中,如果定义了__STRICT_ANSI__,它们将关闭联合。我知道如何通过编译器标志来解决这个问题,但是我不想知道为什么他们会在那里有这个,并且在什么情况下这很重要?
代码来自Apple的来源:
#if defined(__STRICT_ANSI__)
struct _GLKVector4
{
float v[4];
} __attribute__((aligned(16)));
typedef struct _GLKVector4 GLKVector4;
#else
union _GLKVector4
{
struct { float x, y, z, w; };
struct { float r, g, b, a; };
struct { float s, t, p, q; };
float v[4];
} __attribute__((aligned(16)));
typedef union _GLKVector4 GLKVector4;
#endif
答案 0 :(得分:4)
这种保护用于使用非标准结构或特定于某些开发工具的代码。对于完全相同的问题,Microsoft标题中也存在同样的问题:无名结构/联合。
在您的特定情况下,该定义使用在C11标准之前不允许的无名结构,其中使用值__STDC_VERSION__
定义标准宏201112L
以指示C11支持可用。
这似乎只是旧编译器的预防措施。如果您尝试使用前C11进行编译,则会出现错误。
正确的定义应该是:
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ < 201112L)
请注意__STDC_VERSION__
小于201112L
的比较,假设新标准将继续支持无名结构/联合。
无论如何,在我们没有正确识别它们的原因时,必须始终在删除条件编辑之前采取一些谨慎措施。
答案 1 :(得分:3)
我认为他们滥用了__STRICT_ANSI__
宏。它没有被任何标准定义,而只是由GCC和兼容的编译器来表示您使用-std=c99
/ -std=c11
/ etc。在这种情况下,默认情况下系统头不应该污染命名空间C标准不允许的任何内容。
如果图书馆以某种hackish方式使用联盟,但实际上并不是有效的C(例如有未定义的行为)但是GCC允许这样做,他们不应该使用#ifndef __STRICT_ANSI__
而是使用#ifdef __GNUC__
。
在任何情况下,很难确定在没有看到实际代码的情况下告诉你什么,但我很确定你可以忽略它。