有没有办法让gcc或clang在显式转换时发出警告?

8
我想做的是在我手头的一些源文件中找到所有从double或float类型显式转换为其他类型的操作。是否有gcc内置方法可以实现这一点? 编程语言是C。 谢谢!

2
也许我太简单了,但是你不能在源代码中搜索(double)(float)吗? - Robert Harvey
抱歉,@RobertHarvey,我重新组织了一下句子以使其更有意义。我想捕获所有从float/double类型到其他任何类型的显式转换,这样我就可以搜索(int)等内容,但我无法确定它们是float还是double。 - Chris
2
只是一个想法(我不知道C++是否可行):重载double和float的转换运算符,以发出编译失败并将其编译为C++ :) - pmg
@pmg 听起来很有趣,但我对如何开始做那方面知之甚少。 - Chris
1
@user1071861:我问了是否有可能:https://dev59.com/L2PVa4cB1Zd3GeqP2h_l - pmg
@pmg - ...并且了解到它并不是这样。 - Jirka Hanika
5个回答

10
如果你的C代码也可以在C++模式下编译,则可以使用g++的-Wold-style-cast警告标志,在所有此类转换中触发警告。
您可以通过使用Clang的-Weverything开关确定它是否有任何警告,这些警告将对特定编码模式触发(但请注意,这对于几乎任何其他目的都没有用处--clang已禁用了默认情况下触发各种合法代码形式的警告)。但是,在这种情况下,Clang没有任何警告会在此类转换上触发。

2

由于强制转换是明确合法的,并且执行奇怪的转换的正确方法,因此gcc很可能不会包含警告它们的选项。

相反,根据您的源代码有多大,您可能可以这样做:

grep '\(double|float\) ' *

为了给您提供所有的双精度或浮点数变量。由于C语言不是一种常规语言,使用shell工具将其解析为双精度或浮点数变量列表并不容易,但如果您的源代码足够小,则手动完成这个过程很容易。

grep '([^()]*)[ ()]*\(your list of variable names\)' *

从那里,您将看到许多您的投掷。

2

-Wconversion选项用于警告可能会改变值的隐式转换(double是大型类型),而-Wno-sign-conversion选项则禁止在有符号和无符号整数之间进行转换时发出警告(这样就可以减少不必要的警告)。否则,我没有看到任何标准的替代方案...

最坏的情况是您可以直接在源文件中查找这些关键字...


1
据我所知,显式转换不会被 -Wconversion 捕捉到,事实上它们是消除警告的一种方式。我进行了几次测试,发现这也是正确的,因此我需要找到其他方法来解决这个问题。 - Chris
不幸的是,它们被显示出来了(至少在我几个月前尝试时是这样)。我已经启用了-Wconversion来捕获“意外”的转换,而明确(且有意)的转换产生的噪音是无法忍受的。 - Damon

2

虽然我所知道的编译器没有这样的选项,但Gimpel的FlexeLint可以满足您的要求:

$ cat tst.c
int main (void)
{
    int i = 0, j = 0;
    float f = 0.0;
    double d = 0.0;

    i = (int) f;
    j = (int) d;
    d = (double) f;
    f = (float) d;
    i = (int)j;
    j = (unsigned) i;
    return (int) j;
}

$ flexelint -w1 +e922 tst.c
FlexeLint for C/C++ (Unix) Vers. 9.00j, Copyright Gimpel Software 1985-2012

--- Module:   tst.c (C)
               _
    i = (int) f;
tst.c  7  Note 922: cast from float to int
               _
    j = (int) d;
tst.c  8  Note 922: cast from double to int
                  _
    d = (double) f;
tst.c  9  Note 922: cast from float to double
                 _
    f = (float) d;
tst.c  10  Note 922: cast from double to float

shell returned 4

0
嗯,我认为没有这样的选项。毕竟,编译器发出警告是为了提醒你可能无意中做出的操作。然而,显式转换基本上就像是告诉编译器“闭嘴,我知道我在做什么”。

我担心的不是浮点数或双精度浮点数本身,而是从浮点数或双精度浮点数转换到其他类型。我创建了一个包含所有强制转换的列表,但我需要从该列表中提取仅为浮点数或双精度浮点数的变量名称,这对我来说非常困难。 - Chris
在这里,哪种类型的转换是有问题的?如果它们有问题,为什么它们会首先出现在代码中呢? - cli_hlt
2
@cli_hlt:你知道,有些糟糕的代码需要改进到更好的状态 :) - Niklas B.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接