【问题标题】:C Compiler Warnings for Dangerous Casts危险类型转换的 C 编译器警告
【发布时间】:2021-11-16 23:32:42
【问题描述】:

对于我所知道的所有 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)));
}

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

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

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

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

【问题讨论】:

  • C 中类型转换的许多要点是告诉编译器,“我保证我知道我在做什么,所以不要抱怨。”所以我认为你不太可能找到一个编译选项告诉编译器,“继续,然后再猜我。”
  • 这并非史无前例。像 gcc 的 -Wcast-align=strict 这样的编译器选项指示编译器对用户进行第二次猜测,并对某些显式转换发出警告。
  • 对于clang,答案是否定的。它有一个方便的-Weverything 选项,可以启用它实现的每个警告,这不会在您的代码上给出相关警告。 godbolt.org/z/91vEPKjz3

标签: c gcc clang compiler-warnings gcc-warning


【解决方案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]

【讨论】:

  • 哎呀(也许) - 当我以 Win32 为目标时, 生成警告 - 而不是在我以 x64 为目标时。看起来很奇怪。
  • GCC 有一个类似的标志,它可以用作-Wcast-align=strict 以获取此警告,即使在针对 x64 时也是如此。不幸的是,这只捕获对齐不同的情况。除非结构碰巧有不同的对齐方式,否则它不会对不兼容的结构转换发出警告。出于原始问题的目的,此标志会导致误报,因为从 int* 转换为以 int* 开头的 8 字节对齐结构将导致警告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
相关资源
最近更新 更多