我想知道为什么gcc(4.6.3)没有给我这个例子中无法访问的代码的警告:
#include <stdio.h>
int status(void)
{
static int first_time = 1;
if (first_time) {
return 1;
first_time = 0; /* never reached */
} else {
return 0;
}
}
int main(int argc, const char *argv[])
{
printf("first call %d\n", status());
printf("second call %d\n", status());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
注意,故障status()功能的目的是保持状态.我曾期望得到一个警告-Wall.我也试过了-Wunreachable-code,-Wextra(-pedantic和这里-ansi讨论的那样).然而,这些都没有给我一个警告.
看来gcc会默默地删除静态变量赋值.
在我看来,gcc选项-Wall -Werror应该抛出一个错误.
这个问题是关于C++ 20的[[likely]]/ [[unlikely]]功能,而不是编译器定义的宏.
这个文档(cppreference)只给出了一个将它们应用于switch-case语句的例子.这个switch-case示例与我的编译器完美编译(g ++ - 7.2),所以我假设编译器已经实现了这个功能,尽管它还没有在当前的C++标准中正式引入.
但是当我像这样使用它们时if (condition) [[likely]] { ... } else { ... },我收到了一个警告:
"警告:语句开头的属性被忽略[-Wattributes]".
那么我应该如何在if-else语句中使用这些属性呢?
本网站上的几个问题揭示了混合有符号和无符号类型时的缺陷,大多数编译器似乎都很好地生成了这种类型的警告.但是,GCC在将有符号常量赋值给无符号类型时似乎并不在意!考虑以下程序:
/* foo.c */
#include <stdio.h>
int main(void)
{
unsigned int x=20, y=-30;
if (x > y) {
printf("%d > %d\n", x, y);
} else {
printf("%d <= %d\n", x, y);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用GCC 4.2.1进行编译如下所示在控制台上没有输出:
gcc -Werror -Wall -Wextra -pedantic foo.c -o foo
Run Code Online (Sandbox Code Playgroud)
生成的可执行文件生成以下输出:
$ ./foo
20 <= -30
Run Code Online (Sandbox Code Playgroud)
在将有符号值分配给-30无符号整数变量时,是否有某些原因导致GCC不生成任何警告或错误消息y?
我刚刚决定改变所有变量unsigned,int并在重新编译有问题的代码时受到此警告消息的欢迎:
freespace_state.c:203: warning: assuming that the loop is not infinite
Run Code Online (Sandbox Code Playgroud)
有问题的一行:
for (x = startx; x <= endx; ++x, ++xptr)
Run Code Online (Sandbox Code Playgroud)
这个循环是60行代码(包括空格/括号等),并且goto在其中有一个,并且至少出现一次continue.
在这种情况下,我认为我很欣赏GCC假设这个循环不是无限的,因为它永远不应该无限循环.
GCC试图在这里告诉我什么?
警告的语法几乎暗示警告应该在某些其他警告的范围内进行,但在该背景下没有警告.
[编辑] 这完全是我自己的错.我从这里的一个问题偷了一些优化和警告选项而没有真正理解它们,并且从此忘记了它们.
请参阅Mark Rushakoff的回答,此外,我还习惯-Wunsafe-loop-optimizations明确警告GCC是否对循环做出假设.请参阅http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
我正在经历一个非常奇怪的问题gcc-4.7 (Ubuntu/Linaro 4.7.2-11precise2) 4.7.2.我没有警告就无法编译以下有效代码:
extern void dostuff(void);
int test(int arg1, int arg2)
{
int ret;
if (arg1) ret = arg2 ? 1 : 2;
dostuff();
if (arg1) return ret;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译选项和输出:
$ gcc-4.7 -o test.o -c -Os test.c -Wall
test.c: In function ‘test’:
test.c:5:6: warning: ‘ret’ may be used uninitialized in this function [-Wmaybe-uninitialized]
Run Code Online (Sandbox Code Playgroud)
但是,以下代码编译时没有警告(虽然组装效率稍低):
extern void dostuff(void);
int test(int arg1, int arg2)
{
int ret;
if (arg1 && arg2) ret = 1;
if (arg1 && …Run Code Online (Sandbox Code Playgroud) 维基说:
的
extern关键字的意思是"没有限定声明".换句话说,它是一种显式声明变量或强制声明而无需定义的方法.也可以明确定义变量,即强制定义.这是通过为变量分配初始化值来完成的.
这意味着,初始化变量的extern声明用作该变量的定义.所以,
/* Just for testing purpose only */
#include <stdio.h>
extern int y = 0;
int main(){
printf("%d\n", y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
应该是有效的(在C++ 11中编译).但是当使用-Wall -Wextra -pedantic -std=c99GCC 4.7.2中的选项进行编译时,会产生警告:
[Warning] 'y' initialized and declared 'extern' [enabled by default]
Run Code Online (Sandbox Code Playgroud)
哪个不应该.据我所知,
extern int y = 0;
Run Code Online (Sandbox Code Playgroud)
实际上是一样的
int i = 0;
Run Code Online (Sandbox Code Playgroud)
这里出了什么问题?
如果我正确地阅读了C++ ISO规范(第5.8.2和5.8.3节),则负签名类型的右移是特定于实现的,并且是左移未定义的行为.
因此,我想在我们使用g ++ 4.8.2编译的遗留源代码中找到对签名类型的移位操作.
不幸的是,我在手册中找不到这样的选项.我可以使用"g ++ -Wall -Wextra -pedantic"编译此代码,而不会发出警告:
int si = -1;
int left = si << 1; // -2 (multiplication by 2, sign is preserved)
int right = si >> 1; // -1 (no change, only 1s)
Run Code Online (Sandbox Code Playgroud)
任何人都可以告诉我是否有这样的警告,如果没有,为什么gcc不关心它?
在gcc4.4.5中,我发出以下代码的警告.
char *f(void)
{
char c;
return &c;
}
Run Code Online (Sandbox Code Playgroud)
但是,当我使用临时指针时,不再有警告(即使行为是错误的).
char *f(void)
{
char c;
char *p = &c;
return p;
}
Run Code Online (Sandbox Code Playgroud)
我听说在C中指针分析很困难,但可以gcc警告这样的代码吗?
当我编译我的库时,我已经开启了,-fPIC因为我希望能够将其编译为共享库,但也可以作为静态编译.
在cygwin上使用gcc 3.4.4我在所有源文件上收到此警告:
-fPIC ignored for target (all code is position independent)
Run Code Online (Sandbox Code Playgroud)
而且我真的很想知道它有什么意义.它告诉我,我使用的开关没有效果,因为开关应该已经完成了.嗯,这意味着它是多余的,很好.但它有什么意义呢?我该如何压制它呢?
我不是在谈论为什么使用PIC,而是为什么它会产生IMO无用的警告.
编译以下代码
template <typename X, typename F>
auto apply(X x, F f)
{
return f(x);
}
template <typename Y>
auto add_value(Y y)
{
return [y](auto x)
{
return x + y;
};
}
int main()
{
apply(1, add_value(2));
}
Run Code Online (Sandbox Code Playgroud)
用g ++(egv 5.4)给出阴影警告.
$ g++ -Wshadow -Werror -std=c++14 shadow_test.cpp
shadow_test.cpp: In instantiation of ‘add_value(Y)::<lambda(auto:1)> [with auto:1 = int; Y = int]’:
shadow_test.cpp:4:13: required from ‘auto apply(X, F) [with X = int; F = add_value(Y) [with Y = int]::<lambda(auto:1)>]’
shadow_test.cpp:18:26: required …Run Code Online (Sandbox Code Playgroud)