Why does GCC only sometimes detect the use of a variable before its initialization? [duplicate]

半腔热情 提交于 2019-11-28 11:11:58

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:

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:

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

Note, if you remove the:

scanf("%d",&sec);

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.

Also see Better Uninitialized Warnings which says:

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);
                    ^~~

As I note in a comment below at least this case seems to be fixed in gcc 5.0.

With this line:

scanf("%d",&sec);

GCC knows that you initialize sec somewhere in your function.

As a separate step, GCC can do flow analysis to figure out whether you initialize sec before using it. Unfortunately, GCC will not always do the flow analysis you want, or even do flow analysis at all. Sometimes the flow analyis is done at a stage where the other information is not available. So, you cannot count on GCC to figure it out.

Other compilers will figure it out. For example,

~ $ clang-3.7 -c -Wall -Wextra -O2 ex.c                      
ex.c:11:25: warning: variable 'sec' is uninitialized when used here
      [-Wuninitialized]
    printf("sec = %d\n",sec);
                        ^~~
ex.c:5:12: note: initialize the variable 'sec' to silence this warning
    int sec,min,left;
           ^
            = 0
1 warning generated.

It just so happens that GCC is very bad at detecting these errors.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!