C 编译器在打印变量地址时发出警告
我做了一个非常简单的程序来打印两个变量的地址C 编译器在打印变量地址时发出警告,c,gcc,printf,clang,format-specifiers,C,Gcc,Printf,Clang,Format Specifiers,我做了一个非常简单的程序来打印两个变量的地址 #include<stdio.h> int main() { int a,b; printf("%u\n%u",&a,&b); return 0; } #包括 int main() { INTA,b; printf(“%u\n%u”、&a和&b); 返回0; } 但是,Clang-3.7编译器给出如下警告: 警告:format指定类型“unsigned int”,但参数的类型为“int*”[-
#include<stdio.h>
int main()
{
int a,b;
printf("%u\n%u",&a,&b);
return 0;
}
#包括
int main()
{
INTA,b;
printf(“%u\n%u”、&a和&b);
返回0;
}
但是,Clang-3.7编译器给出如下警告:
警告:format指定类型“unsigned int”,但参数的类型为“int*”[-Wformat]`
但是,当我使用GCC-5.x编译时,它没有给出任何警告。哪一个是正确的
我知道的一件事是执行unsigned int num=&a代码>将是错误的,因为地址只能存储在指针中。但是,编译器在打印地址时发出警告是否正确
我根据%p
编译了我的程序。p
是打印地址的正确格式说明符:
printf("%p\n%p",(void*)&a, (void*)&b);
C标准要求与%p
对应的参数应为void*
类型。所以演员都在那里
C11,:
p参数应是指向void的指针。指针的值
转换为打印字符序列,以
实现定义方式
使用不正确的格式说明符是错误的。编译器不需要为未定义的行为生成任何诊断。所以gcc和clang都是正确的
GCC 5.1不会在我的系统上生成警告,而不会产生任何额外的警告
选项。GCC具有更严格的编译器选项:
-Wall-Wextra
。通常,您应该使用最严格的编译器选项进行编译。打印地址(指针)的正确格式说明符是%p
,您需要将参数强制转换为void*
因此,警告是有效的,应该在那里。
但是,当我使用GCC-5.x编译时,它没有给出任何警告
如果是gcc
,请包括-Wall
注释编译器选项并尝试编译。我相信它会发出我们期待的(同样的)警告
注意:实际上,
-Wformat
,它检查提供给printf()
和scanf()
家族调用的参数类型-Wall
启用-Wformat您出现此错误是因为格式说明符%u
接受无符号整数
,而您在代码中提供的是指向内存位置的指针
通过将参数类型指定为(void*)
,可以打印指针所持有的内存位置的地址,这将不会生成错误,并以十进制格式打印内存位置的地址
printf("%u\n%u",(void*)&a,(void*)&b);
printf("%p\n%p",(void*)&a,(void*)&b);
此外,这不是打印指针的正确方法,正确的方法是使用说明符%p
,它将以十六进制格式打印内存位置的地址
printf("%u\n%u",(void*)&a,(void*)&b);
printf("%p\n%p",(void*)&a,(void*)&b);
希望对您有所帮助。IMHO,-Wextra
在这种情况下是不需要的<代码>-墙
就足够了。只要说:)@SouravGhosh Just-Wformat
就足以发现这个特殊问题。但总的来说,用这两种语言编译是个好主意。完全同意。只是想指出确切的选择,没有别的。干杯。感谢您的帮助:-)GCC,如果配置正确(-Wall
)将给出:警告:格式“%u”要求参数类型为“unsigned int”,但参数2的类型为“int*”[-Wformat=]
我认为这个问题(以及发布的答案)是规范副本的一个很好的候选者:)会将其添加到收藏夹中。的可能副本