C 编译器针对危险强制转换的警告

And*_*tin 5 c gcc clang compiler-warnings gcc-warning

对于我所知道的所有 C 编译器,-Wall都会对隐式转换发出警告,但不会对任何显式转换发出警告。我一直在尝试找到一个标志(无论是 gcc、clang、任何 c 编译器都可以),当存在导致未定义或实现定义的行为的强制转换时,该标志将导致发出警告。这是一个示例,说明了我期望和不期望出现警告的位置:

#include <math.h>

struct person {
  int tag;
  char* name;
};

int foo(struct person* p) {
  int* tagPtr = (int*)p; // this cast is fine, cast to first member ptr is allowed
  double* badPtr = (double*)p; // this cast should cause warning
  return ((*tagPtr) + (int)(round(*badPtr)));
}
Run Code Online (Sandbox Code Playgroud)

到 a 的转换int*是明确定义的,并且到double*没有明确定义,但 gcc 不会警告我有关第二次强制转换的信息。有没有办法让它这样做?或者其他编译器甚至 linter 是否提供此功能?

然后是“明确定义的”和“明确定义的实现”之间的区域,即“可以根据上下文进行明确的定义”。例如,如果 a最初是通过另一个方向的转换形成的(由 C 规范的 6.7.2.1p15 节暗示),则从aint*到 a 的转换struct person*是明确定义的。int*指针的出处很少可用,因此编译器或 linter 无法知道此转换是否正确,只知道它可能是正确的。为了对我有用,警告危险强制功能不需要发出警告,仅在保证转换是实现定义的行为的情况下。

有没有一个工具可以帮助解决这个问题?

对于上下文,我正在研究使用 C 作为带有标记变体的语言的目标。如果变体具有不同的尺寸,则铸造是必不可少的。然而,如果编译器可以通过确保我不做任何无意义的转换来帮助现场检查我生成的代码,那就太好了。我怀疑优化编译器应该具有提供此警告的信息,因为这与别名分析所需的信息相同。我只是无法弄清楚是否有任何编译器将信息扭曲到此目的。

Adr*_*ica 1

有没有一个工具可以帮助解决这个问题?

是的:您可以(可选)在 Visual Studio 2019 中安装和使用 clang-cl 编译器。我将您的代码复制/粘贴到我的 VS IDE 中,无需更改,这是 clang 的响应:

警告:从 'struct person *' 转换为 'double *' 会将所需的对齐方式从 4 增加到 8 [-Wcast-align]

运行(静态)代码分析添加了以下内容:

警告 GCC3CDF22:从“struct person *”转换为“double *”将所需的对齐从 4 增加到 8 [clang-diagnostic-cast-align]