c - 是否值得更改 C 声明以增加类型安全性?

标签 c type-conversion header-files void-pointers

我想知道覆盖 header 声明以设置特定类型是否合理或值得。优先于 void * 之类的东西,它不增加类型安全性。

例如,如果您有一个将传感器读数添加到循环缓冲区的通用存储函数:

int add_reading(void *);

为了通用,函数必须定义为 void *。但是,在头文件中,您可以将函数声明为:

int add_reading(my_reading_t *);

这将在 void 指针之上增加一定程度的类型安全性。在通用 header 中,您可以使用默认为 void 的 #define 设置类型。因此覆盖类型可以在#include 之前定义。

这似乎是一个不必要的 hack,但对于不透明指针也可能有同样的争论——使用 opaque_type_t * 而不是 void *。但这至少是定义的行为。我想知道这种困惑是否会调用 UB(未定义行为)?

最佳答案

int add_reading(void *) 声明的函数与用 int add_reading(my_reading_t *) 定义的函数不兼容。根据 C 2018 6.5.2.2 9,C 标准不会定义使用前者声明的标识符(或具有该类型的其他函数指示符)调用后者定义的函数的行为:

If the function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function, the behavior is undefined.

根据 6.7.6.1 2:

For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.

显然,参数类型 void *my_reading_t * 不是指向兼容类型的指针(假设 my_reading_t 是结构类型,不是void 的别名)。

根据 6.7.6.3 15:

For two function types to be compatible,… corresponding parameters shall have compatible types…

关于c - 是否值得更改 C 声明以增加类型安全性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54755874/

相关文章:

double 型到指针型的转换

c - C strcmp 中的字符串比较

java - 如何将 double 转换为具有 2 个小数位的字符串?

c++ - 如何将 std::string 转换为 WCHAR

c++ - 包括外部 header 找出编译器选项

使用 -h 选项时 javac "no source files"

c++ - 在 C 中有效地解析 char 数组

c - 理解为STM32编写的函数

c++ - DVP7010B 显卡 DLL 的 C++ 头文件的 Delphi 转换?

c# - 实现 C# 接口(interface)的 C++ header