编译器在打印变量地址时发出警告
Compiler gives warning when printing the address of a variable
我做了一个非常简单的程序来打印两个变量的地址。
#include<stdio.h>
int main()
{
int a,b;
printf("%u\n%u",&a,&b);
return 0;
}
但是,Clang-3.7 编译器发出警告如下:
warning: format specifies type 'unsigned int' but the argument has type 'int *' [-Wformat]`
但是,当我用 GCC-5.x 编译时,它没有给出任何警告。哪一个是正确的?
我知道的一件事是 unsigned int num=&a;
是错误的,因为地址只能存储在指针中。但是,编译器在打印地址时给出警告是否正确?
编译了我的程序
%p
是打印地址的正确格式说明符:
printf("%p\n%p",(void*)&a, (void*)&b);
C标准要求%p
对应的参数应该是void*
类型。所以演员表在那里。
C11, Reference:
p The argument shall be a pointer to void. The value of the pointer
is converted to a sequence of printing characters, in an
implementation-defined manner.
使用不正确的格式说明符 undefined behavior。 不需要编译器来为未定义的行为生成任何诊断。所以 gcc 和 clang 都是正确的。
GCC 5.1 确实在我的系统上产生了警告,没有任何额外的
选项。 GCC godbolt produces warnings 具有更严格的编译器选项:-Wall -Wextra
。通常,您应该使用最严格的编译器选项进行编译。
用于打印地址(指针)的正确格式说明符是 %p
,您需要将参数转换为 void *
。
因此,警告是有效的,应该存在。
But, when I compiled with GCC-5.x, it gave no warnings
如果是gcc
,请包含-Wall
注意编译器选项并尝试编译。我相信它会抛出我们期望的(相同的)警告。
注意:实际上,-Wformat
会检查提供给 printf()
和 scanf()
系列调用的参数类型。 -Wall
启用 -Wformat
.
您收到此错误是因为 format-specifier %u
接受 unsigned-integer
,而您在代码中提供的是指向内存位置的指针。
您可以通过将参数类型指定为 (void*)
来打印指针持有的内存位置的地址,这将不会产生错误并以十进制格式打印内存位置的地址。
printf("%u\n%u",(void*)&a,(void*)&b);
此外,这不是打印指针的正确方法,正确的方法是使用说明符%p
,它将以十六进制格式打印内存位置的地址。
printf("%p\n%p",(void*)&a,(void*)&b);
希望对您有所帮助。
我做了一个非常简单的程序来打印两个变量的地址。
#include<stdio.h>
int main()
{
int a,b;
printf("%u\n%u",&a,&b);
return 0;
}
但是,Clang-3.7 编译器发出警告如下:
warning: format specifies type 'unsigned int' but the argument has type 'int *' [-Wformat]`
但是,当我用 GCC-5.x 编译时,它没有给出任何警告。哪一个是正确的?
我知道的一件事是 unsigned int num=&a;
是错误的,因为地址只能存储在指针中。但是,编译器在打印地址时给出警告是否正确?
%p
是打印地址的正确格式说明符:
printf("%p\n%p",(void*)&a, (void*)&b);
C标准要求%p
对应的参数应该是void*
类型。所以演员表在那里。
C11, Reference:
p The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.
使用不正确的格式说明符 undefined behavior。 不需要编译器来为未定义的行为生成任何诊断。所以 gcc 和 clang 都是正确的。
GCC 5.1 确实在我的系统上产生了警告,没有任何额外的
选项。 GCC godbolt produces warnings 具有更严格的编译器选项:-Wall -Wextra
。通常,您应该使用最严格的编译器选项进行编译。
用于打印地址(指针)的正确格式说明符是 %p
,您需要将参数转换为 void *
。
因此,警告是有效的,应该存在。
But, when I compiled with GCC-5.x, it gave no warnings
如果是gcc
,请包含-Wall
注意编译器选项并尝试编译。我相信它会抛出我们期望的(相同的)警告。
注意:实际上,-Wformat
会检查提供给 printf()
和 scanf()
系列调用的参数类型。 -Wall
启用 -Wformat
.
您收到此错误是因为 format-specifier %u
接受 unsigned-integer
,而您在代码中提供的是指向内存位置的指针。
您可以通过将参数类型指定为 (void*)
来打印指针持有的内存位置的地址,这将不会产生错误并以十进制格式打印内存位置的地址。
printf("%u\n%u",(void*)&a,(void*)&b);
此外,这不是打印指针的正确方法,正确的方法是使用说明符%p
,它将以十六进制格式打印内存位置的地址。
printf("%p\n%p",(void*)&a,(void*)&b);
希望对您有所帮助。