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=]
我认为这个问题(以及发布的答案)是规范副本的一个很好的候选者:)会将其添加到收藏夹中。的可能副本