c - 是否有将双指针转换为单指针的编译器警告?
问题描述
考虑下面的代码,它是我做 IRL(并且已经做过几次)的简化版本,其中有一个不应该存在的“额外”地址运算符。
#define HEAD \
int type
struct my_struct {
HEAD;
};
struct my_struct_extended {
HEAD;
int a;
int b;
};
int my_function(const struct my_struct *data) {
return data->type;
}
struct my_struct_extended global = { 2, 3, 4 };
int main (int argc, char **argv) {
struct my_struct_extended *local = &global;
// ADDRESS-OF SHOULD NOT BE HERE \/
return my_function((struct my_struct *) &local);
}
有 to 结构,一种基本结构和一种扩展结构。扩展结构的一个实例被强制转换为要在my_function()
. 然而,由于错误的地址操作符,该函数基本上开始处理垃圾数据。
当您将双指针传递给需要单指针的函数时,编译器(在我的情况下为 GCC)总是会发出警告,但是当需要强制转换结构时,会屏蔽此类错误。我猜编译器将转换解释为“是的!我真的想要这个”或其他东西。
是否有可以启用的警告来捕获此问题?
注意:真实世界的情况是涉及以下类型的演员表struct sockaddr
:
ret = rrr_ip_send (
&err,
ip_data->ip_udp.fd,
// EXTRA ADDRESS-OF \/
(struct sockaddr *) &addr,
addr_len,
(void *) send_data,
send_size
);
解决方案
这种在 C 中手工编写继承的代码并不少见,但您确实需要非常小心并定义您的函数,以根据其在层次结构中的位置严格采用继承的类型指针或基类型指针。不幸的是,您的示例中地址运算符的拼写错误只是一个错误,由于强制转换,它可以隐藏在这些设计中。减轻这种情况的一种方法是将所有转换作为单独的行表达式进行,并带有适当的注释,例如:
#define HEAD \
int type
struct my_base_struct {
HEAD;
};
struct my_derived_struct {
struct my_base_struct base;
int a;
int b;
};
int my_base_function(const struct my_base_struct *self) {
return self->type;
}
struct my_derived_struct global = (struct my_derived_struct){ .base.type = 2 };
int main (int argc, char **argv) {
struct my_derived_struct *local_derived = &global;
// get base pointer
struct my_base_struct *base = (my_base_struct *)local_derived;
return my_base_function(base);
}
这会提醒其他人注意正在尝试的诡计。
顺便说一句: sockaddr 结构的重载是一个臭名昭著的混乱来源。
推荐阅读
- azure - 使用 RestAPI 筛选 Azure DevOps 版本
- python - 了解 CCCrypt
- python - x.strip() 与 python 中的 for
- r - 使用R将两列的内容合并为一列
- javascript - 如何通过 Jquery 添加 rails html 标签?
- ipfs - 我的 ipfs 节点连接了零个对等点,当我连接到我的家庭网络 0 个对等点并且蜂窝数据连接到我的计算机时,节点工作正常
- android - 在 Android 中使用 USB 网络摄像头时无法使用设备麦克风
- c++ - 如何为索引数次打印整数数组的索引。例如:如果 index = 3 则打印 3 三次
- reactjs - React Navigation 多个挂载
- angular - 数据未以下拉模板驱动形式显示