如何检查C中的指针是否属于某种类型?
如何检查指针是否属于某种类型 使用如何检查C中的指针是否属于某种类型?,c,gcc,C,Gcc,如何检查指针是否属于某种类型 使用sizeof是不够的 我试图避免将id号放入结构中以标识其类型。假设gcc可能会在流程中的某个位置放置一个结构定义,并将该定义映射到指针处分配的内存。如果这是真的,我想会有办法检查指针类型。你不能。 指针只存储地址,与地址内容无关。不,任何地方都没有运行时类型信息 您应该编写函数,以便函数签名携带类型信息,并让编译器静态检查类型。例如,void burp\u foo(struct foo*thefoo)告诉我们参数是指向struct foo的指针。由调用方提供一
sizeof
是不够的
我试图避免将id号放入结构中以标识其类型。假设gcc可能会在流程中的某个位置放置一个结构定义,并将该定义映射到指针处分配的内存。如果这是真的,我想会有办法检查指针类型。你不能。
指针只存储地址,与地址内容无关。不,任何地方都没有运行时类型信息
您应该编写函数,以便函数签名携带类型信息,并让编译器静态检查类型。例如,
void burp\u foo(struct foo*thefoo)
告诉我们参数是指向struct foo
的指针。由调用方提供一个。当然,通过类型转换,可以提供任何指针指向“代码>结构FoO < /C>”,但这是调用方的问题,而不是您的问题。 < P>您不能在C中这样做。实际上,C++编译器执行了您想要的(将类的类型存储到分配的内存中的信息)。在C中没有类,只有结构,它不包含任何开销。在C中没有类似的东西。指针要么是特定类型的,要么是void*。在C++中没有函数重载或内置运行时多态性。不过,您可以使用函数指针执行伪面向对象技巧,如:
typedef void (*cmd_func)( int );
struct command
{
int arg;
cmd_func action;
};
指针是类型。更一般地说,C不提供内省功能。没有编程方法来确定变量的类型。我试图避免将idnumbers放入结构中以识别其类型。不要避免这样做。如果您确实希望能够检查类型,请将typeID作为每个结构的第一个元素。您的冲动还不错。Gcc不会将结构定义放在运行时的任何位置。这意味着您不能将其作为标准 它可能取决于您使用类型信息的目的。两个主要应用可能是:
对于序列化类型,通常使用您建议的值进行标记。这些标记不必和内存中的数据一起存储。它们可以由输出例程添加 C标准不允许直接这样做。C++标准有一定的能力(<代码>动态> CAST < /COD>和<代码> Type ID>代码>
typeof
GCC附带了一个工具,根据您所做的工作,它可能会很有用
条件运算符
条件运算符(如:代码>X= y==0?1:0;)中的条件运算符和冒号(该文是关于C++的,但条件运算符的类型安全性在C中是相同的)。至少可以说,它的用途并不明显
这两种技术(typeof
和条件运算符)仅限于编译时可用的信息。也就是说,您不能将void*
传递给函数,然后使用typeof
计算指针指向该函数内部的对象的原始类型(因为在编译时该函数内部没有此类信息)
关于这个问题,GTK+是用C编写的,你可以考虑仿真。看起来他们使用的是类型ID,但不是将ID放在结构中,而是使用宏进行查找。避免将ID成员放在结构中的一种方法是使用多态性,如:
typedef struct {
char const *name;
int id;
/* ... */
} object_info_t;
typedef struct {
object_info_t *info;
} object_t;
typedef struct {
object_t object;
int a;
} foo_t;
typedef struct {
object_t object;
int b;
} bar_t;
int object_get_id(object_t *object)
{
return object->info->id;
}
注意:您可以使用函数指针扩充object\u info\t
,同时避免检查id
s:
typedef struct {
char const *name;
int id;
int (*do_something)(object_t *);
} object_info_t;
int object_do_something(object_t *self)
{
return self->info->do_something(self);
}
所有贴在这里的答案都是“你不能”,他们是对的。你不能 但是,我甚至不愿提及,有一些游戏可以玩。这些游戏是个坏主意。在任何情况下我都不推荐它们 游戏是什么?在地址的未使用部分中填充多余的数据位,并在使用地址的任何地方将其剥离 假设你有指向32字节大小的结构或类的指针。如果确保内存分配与32字节地址对齐(这对于动态分配来说很容易,但对于堆栈分配来说更难保证),那么地址的低位将全部为0。这意味着地址底部有5个空闲位,足以让您放置标志、ID号、状态值等。存储是空闲的! 即使你有一个奇特的结构大小,实际上任何C或C++编译器和OS都会将每个地址对齐到4个字节。 在64位中,您通常可以在地址的高端找到大量空闲位。。。很可能有16个空闲未使用的位,正在等待您。当然,这取决于操作系统。也是一个糟糕的坏主意。你喜欢危险,不是吗 两个不利因素是:
(来源:) 有太多的方式,这将爆炸成错误,崩溃,和痛苦。雷姆