我的测试代码:
#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
被完整地签名。
谢谢。
答案 0 :(得分:1)
Default argument promotions应用于可变函数的操作数。在这些条件下,类型unsigned char
的表达式被提升为int
。
答案 1 :(得分:1)
在C和C ++中,比int窄的类型总是提升为int。参见Why must a short be converted to an int before arithmetic operations in C and C++?
内部可变参数函数中的默认提升也适用,这意味着您不能将比int窄的类型传递给vararg函数。因此uint8_t
必须用%d
而不是%u
打印。但是无论如何,您打印的方式都是错误的。正确的方法是使用PRIu8
printf("%" PRIu8 "\n", x);
答案 2 :(得分:0)
要使用uint8_t
打印printf()
变量,应执行以下操作:
#include <cinttypes>
#include <cstdio>
int print_u8(std::uint8_t x) {
return std::printf("%" PRIu8 "\n", x);
}
<cinttypes>
标头包含应用于最大可移植性的所有<cstdint>
类型的printf和scanf格式说明符(并显式包括该标头)。