GCC将uint8_t和uint16_t解释为已签名? [重复]

问题描述 投票:0回答:3

这个问题在这里已有答案:

我的测试代码:

#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。

谢谢。

linux c++11 gcc
3个回答
1
投票

Default argument promotions适用于可变函数的操作数。在这些之下,unsigned char类型的表达被提升为int


1
投票

在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);

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格式说明符(并明确包含该头文件),应该用于最大程度的可移植性。

© www.soinside.com 2019 - 2024. All rights reserved.