为什么GCC只是有时检测其初始化之前使用一个变量? [英] Why does GCC only sometimes detect the use of a variable before its initialization?

查看:158
本文介绍了为什么GCC只是有时检测其初始化之前使用一个变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在读一本书,有的code,当我决定做出改变,看看的初始化值将是<$ C之前$ C>,而语句:

I was reading some code from a book, when I decided to make a change to see what the uninitialized value of sec would be before the while statement:

#include<stdio.h>

#define S_TO_M 60

int main(void)
{
    int sec,min,left;

    printf("This program converts seconds to minutes and ");
    printf("seconds. \n");
    printf("Just enter the number of seconds. \n");
    printf("Enter 0 to end the program. \n");
    printf("sec = %d\n",sec);
    while(sec > 0)
    {
        scanf("%d",&sec);
        min = sec/S_TO_M;
        left = sec % S_TO_M;
        printf("%d sec is %d min, %d sec. \n",sec,min,left);
        printf("Next input?\n");
    }
    printf("Bye!\n");

    return 0;
}

这编译下GCC没有警告,即使在这一点上未初始化,我也得到 32767

This compiles under GCC with no warnings, even though sec is uninitialized at that point, and I get a value of 32767:

$ gcc -Wall test.c
$ ./a.out 
This program converts seconds to minutes and seconds. 
Just enter the number of seconds. 
Enter 0 to end the program. 
sec = 32767

但是,当我注释掉,而语句:

#include<stdio.h>

#define S_TO_M 60

int main(void)
{
    int sec;
    //min,left;

    printf("This program converts seconds to minutes and ");
    printf("seconds. \n");
    printf("Just enter the number of seconds. \n");
    printf("Enter 0 to end the program. \n");
    printf("sec = %d\n",sec);
    /*
    while(sec > 0)
    {
        scanf("%d",&sec);
        min = sec/S_TO_M;
        left = sec % S_TO_M;
        printf("%d sec is %d min, %d sec. \n",sec,min,left);
        printf("Next input?\n");
    }
    */
    printf("Bye!\n");

    return 0;
}

现在GCC发出警告和最终被零:

Now GCC issues a warning and sec ends up being zero:

$ gcc -Wall test.c
test.c: In function ‘main’:
test.c:12:8: warning: ‘sec’ is used uninitialized in this function[-Wuninitialized]
printf("sec = %d\n",sec);
    ^
$ ./a.out
This program converts seconds to mintutes and seconds. 
Just enter the number of seconds. 
Enter 0 to end the program. 
sec = 0
Bye!

为什么警告显示在第二个时间,但不是第一次?

Why did the warning show up the second time but not the first time?

推荐答案

显然 GCC 有这个选项漏报长时间运行的问题,看到这个错误报告:<一HREF =htt​​ps://gcc.gnu.org/bugzilla/show_bug.cgi?id=18501相对=nofollow>错误18501 - [4.8 / 4.9 / 5的回归]缺少使用未初始化警告(CCP)< /重复一>和长长的名单:

Apparently gcc has a long running problem with false negatives with this option see this bug report: Bug 18501 - [4.8/4.9/5 Regression] Missing 'used uninitialized' warning (CCP) and the long list of duplicates:

重复:30542 30575 30856 33327 36814 37148 38945 39113 40469 42724 42884 45493 46684 46853 47623 48414 48643 49971 56972 57629 58323 58890 59225 60444

Duplicates: 30542 30575 30856 33327 36814 37148 38945 39113 40469 42724 42884 45493 46684 46853 47623 48414 48643 49971 56972 57629 58323 58890 59225 60444

这是朝着结束注释说明,我们可以看到这已经超过十年当前的一个问题:

Note from comment towards the end, we can see this has been an ongoing issue for over ten years:

今年将是这个bug的10周年。我们要订购的蛋糕!

Hey guys, this year will be the 10 year anniversary of this bug. We should order cake!

请注意,如果你删除:

scanf("%d",&sec);

您也将收到警告,马克Glisse还指出,删除前四的printf 也可以作为很好(的看直播 的)。我没有看到一个类似的例子在重复,但不知道它是工作增加另一个bug报告这一点。

you will also receive a warning, Marc Glisse also points out removing the first four printf also works as well (see it live). I don't see a similar example in the duplicates but not sure it is work adding yet another bug report for this.

另请参见更好的未初始化警告它说:

GCC有警告用户使用未初始化变量的值的能力。这样的价值是不确定的,它从来不会有用。这不是一个随机值,即使有用,因为它很少是一个随机值。不幸的是,当使用一个未初始化的变量的是检测等效,在一般情况下,为了解决停机问题。 GCC尝试通过使用优化器收集到的信息来检测某些情况下,当选项-Wuninitialized在命令行给出警告他们。有许多的在当前实现明显不足。首先,当优化是通过-O1,-O2或-O3启用它仅适用。二,设置假阳性或假阴性根据启用的优化而变化。这也导致最佳化时添加或发行版之间修改报告的警告的高变异性。

GCC has the ability to warn the user about using the value of a uninitialized variable. Such value is undefined and it is never useful. It is not even useful as a random value, since it rarely is a random value. Unfortunately, detecting when the use of an uninitialized variable is equivalent, in the general case, to solving the halting problem. GCC tries to detect some instances by using the information gathered by optimisers and warns about them when the option -Wuninitialized is given in the command line. There are a number of perceived shortcomings in current implementation. First, it only works when optimisation is enabled through -O1, -O2 or -O3. Second, the set of false positives or negatives varies according to the optimisations enabled. This also causes high variability of the warnings reported when optimisations are added or modified between releases.

一个侧面说明,似乎赶上这种情况就好了(看到活生生的例子 的):

A side note, clang seems to catch this case just fine (see live example):

 warning: variable 'sec' is uninitialized when used here [-Wuninitialized]
printf("sec = %d\n",sec);
                    ^~~

正如我在评论下面的注释至少这种情况下,似乎是固定在 GCC 5.0

这篇关于为什么GCC只是有时检测其初始化之前使用一个变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆