我最近一直试图通过一些C基础知识来尝试建立对低级语言的基本理解。
在我遇到的一个文件中(A tutorial on pointers and arrays in C)
作者在printf
语句中使用了一个void指针:
int var = 2;
printf("var has the value %d and is stored at %p\n", var, (void *) &var);
说明原因:
我将指向整数的指针转换为void 指针使它们与%p转换规范兼容。
但是,省略(void *)
不会导致错误或警告,无法编译,运行或正在valgrind
运行。
int var = 2;
printf("var has the value %d and is stored at %p\n", var, &var);
在这里被视为无效的最佳做法或标准,或者是否有一些更加险恶的东西?
答案 0 :(得分:4)
Since printf
is a variadic function, its declaration only specifies the type of the first parameter (the format string). The number and types of any remaining parameters are required to match the format string, but it's up to you, the programmer, to make sure they actually match. If they don't, the behavior is undefined, but the compiler isn't obliged to warn you about it. (Some compilers, including gcc, can do some checking if the format string is a literal.)
The %p
format specifier requires an argument of type void*
. If you pass a pointer of a different type, you have undefined behavior. In many implementations, all pointer types have the same size and representation, and are passed the same way as function arguments -- but the language doesn't guarantee that. By explicitly converting the pointer to void*
, you guarantee that it will work correctly. By omitting the cast, you have code that will probably work as you expect it to on almost all implementations.
100% correct is better than 99% correct, especially if the only cost of that extra 1% is typing a few characters.