基本上,我想要的是某种编译时生成的版本,它与结构的确切定义相关联.如果结构的定义以任何方式改变(字段添加,移动,可能重命名),我也希望该版本也能改变.
在读取先前序列化的结构时,这样的版本常量会很有用,以确保它仍然兼容.另一种方法是手动跟踪一个手动指定的常量,如果忘记递增它会产生混乱效果(反序列化会产生垃圾),并且在准确地增加它时会提出问题(在开发和测试期间,或仅在某种情况下)发布).
这可以通过使用外部工具在结构定义上生成哈希来实现,但我想知道是否可以使用C编译器(和/或其预处理器)本身.
这实际上是某种形式的内省,所以我怀疑这在ANSI C中可能根本不可能,但我会对使用gcc和clang的解决方案感到满意.
Windows API 曾经(现在仍然如此?)将 size 成员作为结构体的第一个成员之一,以便它知道正在传递的结构体版本(参见WNDCLASSEX示例):
struct Foo
{
size_t size;
char *bar;
char *baz;
/* Other fields */
};
Run Code Online (Sandbox Code Playgroud)
在打电话之前,您可以使用以下命令设置尺寸sizeof:
struct Foo f;
f.size = sizeof(struct Foo);
f.bar = strdup("hi");
f.baz = strdup("there");
somefunc(&f);
Run Code Online (Sandbox Code Playgroud)
然后somefunc根据size成员知道它正在处理哪个版本的结构。由于sizeof是在编译时而不是运行时求值,因此可以实现向后 ABI 兼容性。