我最近在笔记本电脑上设置了MinGW + MSYS环境,以检查Netbeans C / C ++支持的情况。一切似乎都运行良好,但是,在我的测试中,我注意到GCC和微软的cl.exe编译器之间存在差异。
以下是一个示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(void) {
int i_max = INT_MAX;
char c_max = CHAR_MAX, c;
c = i_max;
printf("i_max: %d, c_max: %d, c: %d\n", i_max, c_max, c);
return EXIT_SUCCESS;
}
输出结果为:
i_max: 2147483647, c_max: 127, c: -1
正如您在上面的代码中看到的,我将一个int分配给一个char。这不应该产生警告,可能会发生数据丢失吗?微软的编译器(我已经配置得非常严格)会发出警告而GCC没有。
以下是我使用的GCC选项:
-g -Werror -ansi -pedantic -Wall -Wextra
我是否遗漏了一些GCC选项,使编译时间检查更加严格?
答案 0 :(得分:9)
您正在寻找
-Wconversion
您必须向gcc开发人员询问-Wall
或-Wextra
中未包含某些警告的具体原因。
无论如何,这些是我使用的标志:
-Wall -Wextra -Wmissing-prototypes -Wmissing-declarations -Wshadow
-Wpointer-arith -Wcast-align -Wwrite-strings -Wredundant-decls -Wnested-externs
-Winline -Wno-long-long -Wconversion -Wstrict-prototypes
正如其他人所指出的那样,-Wconversion
的行为随version 4.3而变化 - 关于强制进行类型转换的原型的旧警告现在可用-Wtraditional-conversion
。
答案 1 :(得分:2)
-Wall doesn't quite mean -Wall,-Wextra已经因为过分迂腐而受到抨击。
正如Christoph所说,你正在寻找-Wconversion。真正深入了解-Wall和-Wextra实际打开的内容,只需在make文件中指定所需的-W标志,尤其是将警告视为错误时。
答案 2 :(得分:2)
你的问题有点细微差别,从措辞的方式来看,这对我来说并不是很明显。
如果你认为GCC(特别是GCC)应该在这里发出警告,那么一些编译器选项可能会有所帮助(参见其他回复)。
如果你认为任何编译器应该在这里发出警告(我似乎在你的问题中读到这种情绪),那么......好吧,“警告”绝对不是强制性的甚至是事实上是统一的。这里没有“应该”。在没有显式强制转换的情况下将较大类型的整数值分配给较小的类型在C中是完全合法的。转换时溢出会产生实现定义的行为(它甚至不是UB :))
答案 3 :(得分:2)
我也没有收到-Wconversion
的警告/错误。但是,如果您使用splint
之类的通行证,则会收到三条警告:
file.c: (in function main)
file.c:9:5: Assignment of int to char: c = i_max
To make char and int types equivalent, use +charint.
file.c:10:52: Format argument 2 to printf (%d) expects int gets char: c_max
file.c:10:32: Corresponding format code
file.c:10:59: Format argument 3 to printf (%d) expects int gets char: c
file.c:10:39: Corresponding format code
Finished checking --- 3 code warnings
如果您认真捕捉所有错误,则应使用多个工具。
答案 4 :(得分:1)
在C中,为char分配int是合法的。
由于它是合法的(但可能是狡猾的),不同的编译器供应商在遇到这些代码时会做不同的事情。
我猜MS只是在愚蠢,而海湾合作委员会的人已经决定它甚至不值得警告。
答案 5 :(得分:0)
我认为它属于“常用算术转换”(6.3.1.8)或“整数提升规则”(5.1.2.3(?)),但我找不到说明你行为的具体文字看到了。