如何在typedef结构体时保留struct关键字的使用特性?
保留struct关键字的结构体重命名尝试
我想重命名一个结构体类型(比如timespec),但不想丢掉struct关键字的用法——我觉得这样能让读者一眼看出某个对象是结构体,所以希望新名称和普通结构体的表现一致:声明变量或作为函数参数时,必须写struct关键字才能使用。我做了如下尝试:
#include <time.h> #define TYPE_DEF_STR #define D #ifdef TYPE_DEF typedef timespec T; #elif defined (TYPE_DEF_STR) typedef struct timespec T; #endif #ifdef A struct T my_struct; #elif defined (B) T my_struct; #endif int main() { #ifdef C struct T my_struct; #elif defined (D) T my_struct; #endif my_struct.tv_nsec = 5; return 0; }
不同宏组合的编译结果如下:
TYPE_DEF + A:编译报错,提示unknown type name ‘timespec’TYPE_DEF + B:编译报错,提示unknown type name ‘timespec’TYPE_DEF_STR + A:编译报错,提示invalid use of undefined type ‘struct T’TYPE_DEF_STR + B:编译通过TYPE_DEF_STR + C:编译报错,提示storage size of ‘my_struct’ isn’t knownTYPE_DEF_STR + D:编译通过
问题分析
当前尝试没达到预期的核心原因是:typedef struct timespec T;只是给struct timespec这个类型创建了一个别名T,但并没有定义struct T这个带标签的结构体类型。当你写struct T时,编译器会认为这是一个全新的、未定义的结构体,自然会报错。
正确实现方式
要实现“必须写struct关键字才能使用新名称”,你需要给原结构体的标签起别名,而不是给整个类型起typedef别名。最直接的方式是用预处理器宏替换:
#include <time.h> // 让struct T等价于struct timespec #define struct T struct timespec // 使用方式:必须写struct关键字 struct T my_struct; // 等价于struct timespec my_struct; void func(struct T param) { // 处理参数 }
这样写的话,所有struct T都会被预处理器替换为struct timespec,既保留了struct关键字的要求,又实现了重命名的目的,完全符合需求。
内容的提问来源于stack exchange,提问作者user21271517
相关产品推荐
相关产品推荐

