危险转换的 C 编译器警告
C Compiler Warnings for Dangerous Casts
对于我所知道的所有 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*
最初是由另一个方向的转换形成的,那么从 int*
到 struct person*
的转换是明确定义的(由 C 规范的第 6.7.2.1p15 节暗示) .指针的出处很少可用,因此编译器或 linter 不知道此转换是正确的还是不正确的,只知道它可能是正确的。为了对我有用,warn-on-dangerous-cast 功能需要在这种情况下 not 警告,只有在保证强制转换是实现定义的行为的情况下。
有没有工具可以解决这个问题?
对于上下文,我正在研究使用 C 作为具有标记变体的语言的目标。如果变体有不同的尺寸,铸造是必不可少的。但是,如果编译器可以通过确保我没有进行任何无意义的转换来帮助抽查我生成的代码,那就太好了。我怀疑优化编译器应该有提供此警告的信息,因为这与别名分析所需的信息相同。我只是无法弄清楚是否有任何编译器为此目的扭曲了信息。
Is there a tool that can help with this?
是:您可以(可选)在 Visual Studio 2019 年安装和使用的 clang-cl 编译器。我 copy/pasted 您的代码没有更改到我的 VS IDE 中,这是clang 的回复:
warning : cast from 'struct person *' to 'double *' increases required
alignment from 4 to 8 [-Wcast-align]
运行 一个(静态)代码分析添加了这个:
warning GCC3CDF22: cast from 'struct person *' to 'double *' increases
required alignment from 4 to 8 [clang-diagnostic-cast-align]
对于我所知道的所有 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*
最初是由另一个方向的转换形成的,那么从 int*
到 struct person*
的转换是明确定义的(由 C 规范的第 6.7.2.1p15 节暗示) .指针的出处很少可用,因此编译器或 linter 不知道此转换是正确的还是不正确的,只知道它可能是正确的。为了对我有用,warn-on-dangerous-cast 功能需要在这种情况下 not 警告,只有在保证强制转换是实现定义的行为的情况下。
有没有工具可以解决这个问题?
对于上下文,我正在研究使用 C 作为具有标记变体的语言的目标。如果变体有不同的尺寸,铸造是必不可少的。但是,如果编译器可以通过确保我没有进行任何无意义的转换来帮助抽查我生成的代码,那就太好了。我怀疑优化编译器应该有提供此警告的信息,因为这与别名分析所需的信息相同。我只是无法弄清楚是否有任何编译器为此目的扭曲了信息。
Is there a tool that can help with this?
是:您可以(可选)在 Visual Studio 2019 年安装和使用的 clang-cl 编译器。我 copy/pasted 您的代码没有更改到我的 VS IDE 中,这是clang 的回复:
warning : cast from 'struct person *' to 'double *' increases required alignment from 4 to 8 [-Wcast-align]
运行 一个(静态)代码分析添加了这个:
warning GCC3CDF22: cast from 'struct person *' to 'double *' increases required alignment from 4 to 8 [clang-diagnostic-cast-align]