遗憾的是,这在某些外部库中定义:无法触摸!
// library.h
typedef struct {
long foo;
char *bar;
/* ... (long & complex stuff omitted) */
} *pointer_to_complex_struct_t;
现在问题:如何声明 complex_struct_t
变量?
理想的解决方案,但不允许! (不能更改外部库):
// library.h
/* ... (long & complex stuff omitted) */
} complex_struct_t, *pointer_to_complex_struct_t;
// my.h
extern complex_struct_t my_variable;
非便携式解决方案(gcc):
// my.h
extern typeof( * (type_placeholder)0 ) my_variable; // Thanks caf!
其他?更好?谢谢!
奖金问题:函数指针的相同问题(如果有任何差异;我对此表示怀疑)。
ADDED奖励:下面是完全相同的问题,但功能而不是结构。这不应该对简短的回答(“号码”)产生任何影响,这是我最初感兴趣的唯一答案。我没想到有些人会因为创造性的解决方法而知道并完成工作,这就是为什么我简化了从函数到结构的问题(函数指针具有特殊的隐式转换规则,以方便和混淆)。但是,嘿,为什么不呢?让我们开始复制粘贴解决方案竞赛。一些解决方法可能比其他解决方案更好。
///// library.h //////
// Signature has been simplified
typedef double (*ptr_to_callback_t)(long, int, char *);
// Too bad this is not provided: typedef double callback_t(long, int, char *);
///// my.h /////
// This avoids copy-paste but is not portable
typedef typeof( * (ptr_to_callback_t)0 ) callback_t;
extern callback_t callback_1;
extern callback_t callback_2;
extern callback_t callback_3;
// etc.
简短回答=否,目前没有typeof
基本的复制粘贴解决方法适用于功能但不适用于结构。编译器将匹配重复的函数类型,但不会关联重复的结构类型:需要强制转换,并且重复的结构类型将在没有编译警告的情况下发散。
答案 0 :(得分:2)
不,不幸的是你不能用标准的C做。使用C ++,一个简单的元函数可以做到这一点。
但是你可以复制粘贴结构的定义,从而保留原始的
typedef struct {
///same struct
} complex_struct_t;
此解决方案的缺点是表达式&complex_struct_t
不是pointer_to_complex_struct_t
类型,而是指向未命名struct {//your members}
的类型指针;
如果你需要这个功能,你需要reinterpret_casting ...
答案 1 :(得分:1)
如上所述,你的问题的答案是“不”;如果您拥有的是
的类型定义typedef struct {...} *ptr_to_struct;
然后没有(标准的,可移植的)方式来提取结构类型。如果您必须创建结构的实例,那么您将能够做的最好的是
ptr_to_struct s = malloc(sizeof *s);
然后使用->
组件选择运算符(或通过解除引用s
并使用.
运算符引用结构中的字段,但您不希望这样做)。
你问过同样的事情是否适用于函数指针;你真的需要说出你的意思。如果你有像
这样的情况typedef struct {...} *ptr_to_struct;
ptr_to_struct foo() {...}
那么情况就像上面那样;你没有办法声明那种类型的变量。
答案 2 :(得分:0)
制作头文件的本地副本并包含它而不是原始文件。现在你可以做任何你想做的事。如果这个库可以更改(更新或其他任何东西),你可以编写一个小脚本来自动执行这些步骤,并在编译时从makefile中调用它。只需确保不要盲目地粘贴到标题中,搜索特定行(} *pointer_to_complex_struct_t;
)并在不再找到时抛出错误。
如果此标头使用此库的其他标头,则可能必须对包含的搜索路径保持谨慎。另外,如果其他标题包含了包含的顺序。
编辑(为评论中提到的真实目标):你不能用函数指针来做这件事。只需使用typedef的签名编写所需的函数,它就会与指针兼容并可以被它调用。
答案 3 :(得分:0)
怎么样:
pointer_to_complex_struct_t newStruct ( void ) {
pointer_to_complex_struct_t ptr =
(pointer_to_complex_struct_t) malloc ( sizeof (*pointer_to_complex_struct_t) );
return ptr;
}
你必须通过ptr->引用你新创建的结构;但你可以创造新的。
当然,这可能会也可能不会起作用,具体取决于结构的实际使用方式。想到的例子是:如果结构以
结尾,该怎么办?char data[0];
并且数据用于指向结构后面的内存。