我正在寻找一个解释为什么gcc要给我这样的警告。
我正在用gcc-3 on cygwin编写带有-Wunreachable-code标志的代码,gcc为我说了这个警告:
main.c:223:警告:永远不会执行
这句话是:while(fgets(line, MAX_LINE, stdin) != NULL) {
此代码位于if(exp) { }块中,其中exp是根据命令行参数(由getopt()解析)动态设置的,请查看代码部分:
if(mystruct.hastab) {默认值是0。但是,如果将1标志传递给应用程序,则会变成-t,如下所示:
struct mystruct_t {
//...
int hastab;
} mystruct;
int main(int argc, char *argv[])
{
int opt;
memset(&mystruct, 0, sizeof(mystruct));
while((opt = getopt(argc, argv, optString)) != -1) {
switch(opt) {
case 't':
mystruct.hastab = 1;
break;
//....
}
}
proc();
return 0;
}
void
proc(void)
{
char *buf, *tmpbuf, line[MAX_LINE + 1], *p, *fullfilename;
if(mystruct.hastab) {
while(fgets(line, MAX_LINE, stdin) != NULL) {
//...
}
} else {
//...
}
}所以,执行代码是有原因的。恰巧发生了。
发布于 2012-07-20 21:57:40
还有一种可能性:问题在于宏。下面是一个简单的示例,演示了您的错误:
#include <string.h>
int s;
int main(int argc, char *argv[]) {
memset(&s, 0, sizeof(s));
}当我编译它时,我得到:
$ gcc -Wunreachable-code tmp.c
tmp.c: In function ‘main’:
tmp.c:4: warning: will never be executed这一错误并不特别具有启发性。但是,如果运行预处理器,请查看memset扩展到的内容:
$ gcc -E tmp.c
...
int s;
int main(int argc, char *argv[]) {
((__builtin_object_size (&s, 0) != (size_t) -1) ? __builtin___memset_chk (&s, 0, sizeof(s), __builtin_object_size (&s, 0)) : __inline_memset_chk (&s, 0, sizeof(s)));
}我怀疑,由于s的大小不变,只有一个?:分支被执行过,这就是gcc所抱怨的。在您的例子中,可能是fgets是一个宏。运行gcc -E,在输出中找到问题行,看看它是否不可靠(我的不是,但我没有运行cygwin)。
故事的寓意:预处理器和宏太烂了。
发布于 2012-07-20 20:16:16
听起来gcc确信hastab从未被设置过,或者它只是在它警告的代码之后才被设置。当然,gcc似乎错了,但既然你只给了我们一些片段,就很难确定。我认为没有人能进一步帮助你,除非我们看到一个完整的程序,我们可以自己编译。
发布于 2012-07-20 21:45:23
如果我不得不猜的话,我会说gcc在考虑有两种情况下,你可以调用proc(),而不必将mystruct.hastab设置为0以外的东西。
第一种情况是,如果这在第一次运行时会转移到false,因为您将在不执行switch语句的情况下退出循环:
while((opt = getopt(argc, argv, optString)) != -1) {
第二种情况是,如果opt永远不是't'
switch(opt) {
case 't':
mystruct.hastab = 1;因此,在没有将mystruct.hastab设置为非零值的情况下,您将退出循环。
https://stackoverflow.com/questions/11586339
复制相似问题