这个问题在这里已有答案:
我的测试代码:
#include <cstdint>
#include <cstdio>
int main() {
const constexpr uint8_t x = 64;
printf("%u", x);
}
这是我用GCC 8.2编译的方式:
g++ -Wall test_format.cpp -o test_format -O3 -std=c++17 -Wformat-signedness
这是GCC的输出:
test_format.cpp: In function ‘int main()’:
test_format.cpp:6:9: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int’ [-Wformat=]
printf("%u", x);
^~~~
那么,如果我尝试打印uint32_t
,它没有错误/警告。
我想知道为什么GCC希望uint8_t
签署int。
谢谢。
Default argument promotions适用于可变函数的操作数。在这些之下,unsigned char
类型的表达被提升为int
。
在C和C ++类型中,比int更窄的类型总是提升为int。见Why must a short be converted to an int before arithmetic operations in C and C++?
在variadic函数内部,默认促销也适用,这意味着你不能将比int更窄的类型传递给vararg函数。所以uint8_t
必须印有%d
,而不是%u
。但无论如何你以错误的方式打印它。正确的方法是使用PRIu8
printf("%" PRIu8 "\n", x);
要使用uint8_t
打印printf()
变量,您应该执行以下操作:
#include <cinttypes>
#include <cstdio>
int print_u8(std::uint8_t x) {
return std::printf("%" PRIu8 "\n", x);
}
<cinttypes>
头文件包括所有<cstdint>
类型的printf和scanf格式说明符(并明确包含该头文件),应该用于最大程度的可移植性。