假设您正在编写一个C struct,它代表一顿饭中的一道菜。课程中的字段之一struct是以下类型:
enum TP_course {STARTER, MAINCOURSE, DESSERT};
Run Code Online (Sandbox Code Playgroud)
然后,根据课程类型,您有一个子类型:
enum TP_starter {SALAD, GRILLEDVEGETABLES, PASTA};
enum TP_maincourse {BEEF, LAMB, FISH};
enum TP_dessert {APPLEPIE, ICECREAM, MOUSSE};
Run Code Online (Sandbox Code Playgroud)
鉴于一次只使用一个这样的枚举(取决于课程的类型),将它们聚合在一个 中是有意义的union:
union U_subtype {
enum TP_starter s;
enum TP_maincourse m;
enum TP_dessert d;
};
Run Code Online (Sandbox Code Playgroud)
所以课程struct看起来像这样:
struct S_course {
enum TP_course type;
union U_subtype stype;
float price_in_USD;
int availability;
...and all the rest of data would follow...
};
Run Code Online (Sandbox Code Playgroud)
好的,一切都清楚了,但是......我可以遵循任何编码策略来尝试强制安全访问stype上面标记的联合吗?也许以某种方式使它不透明?
例如,如果我switch/case为an写了一个block,enum而忘记case为一个值写a ,编译器就会触发一个警告,这对以后维护代码有很大的帮助。但是如果我在 …
人们通常认为 offsetof() 可以应用于联合(您甚至可以在 SO 的几个问题中找到这种用法),但是,似乎从 C90 到现在的所有 C 规范都只说 offsetof() 宏支持结构。我现在正在看 Jens Gustedt 的《Modern C》一书,表 4.3 指定“struct”作为 offsetof() 第一个参数的类型。
那么,... offsetof() 是否正式支持联合?
根据我的经验,C 预处理器在之前预处理过的源代码上运行时只是表现为无操作。但是这种行为是由标准保证的吗?或者,一个实现可能有一个预处理器来修改以前预处理过的代码,例如删除/修改行指令,或者执行其他可能会混淆编译器的修改?
根据 GCC 文档, -MM 标志将以这种方式生成依赖项:
与 -M 类似,但不提及在系统头目录中找到的头文件,也不提及直接或间接包含在此类头中的头文件。
我刚刚发现在我的项目中使用的 -MM 标志不仅抑制了对系统头文件的依赖,而且还抑制了对我本地安装在我的主目录中的第三方库头文件的依赖。摆脱系统头文件的依赖对我来说通常很方便(因为我不编辑它们),但是我有时会编辑/自定义第三方库,当然我需要在这样的编辑后重建我的代码。
所以,我的问题是 GCC 的“系统标头”是什么?假设您在主目录中安装了自定义版本的 libpng,并对其进行了编辑以满足您的需要……这是 GCC 的“系统头文件”吗?
同时,我只是将 -M 作为临时解决方法。
我知道0.0 == -0.0C 标准所说的if(a)相当于if(a!=0),但是:
保证按标准if(-0.0)评价吗?如果评估为真,false那么实现会出现错误吗?if(-0.0)
我想这里的关键点是是否必须将if(a!=0)的含义理解为与浮点中if(-0.0)完全相同的运算符,在这种情况下可以保证它一定是错误的。!=