【发布时间】:2021-08-24 02:17:36
【问题描述】:
uint64_t、uint32_t、long 和 int(即 stdint 和本机编译器类型)的类型等效性是否发生了变化。还是我遇到了 g++ 错误?
g++ 8.3 中带有 c++17 选项的以下代码编译没有错误。架构是 arm 32 位。
std::stringstream os;
void write(long value)
{
os << value;
}
void write(int64_t value) // G++ 9.4 error: indistinguishable overload.
{
os << value;
}
void write(int32_t value)
{
os << value;
}
long value = 1;
write(longValue); // g++ 8.3: no matching overload, if the write(long) overload is removed.
使用 g++ 9.4 和 c++17 选项编译的相同代码会出错,因为 long 和 in64_t 重载无法区分。 (我所期望的)。
但是删除 write(long) 重载会导致 g++ 8.3 抱怨没有匹配的重载。 (不是我在任何版本的 C++ 标准中所期望的)。
老实说,我不知道为什么 gcc 8.3 版本可以正常工作。如果 uint64_t 是 typedef 的,那么代码应该可以在没有 write(long) 重载的情况下工作,也许是 gcc 8.3 中的一个错误?
当我们在这里的时候:char、uint8_t、int8_t 的等价性如何? (如果它们是不同的,那将是一件好事)。我似乎确实记得 wchar_t 成为与 C++ 中的 uint16_t/int16_t 不同的类型(mumble-mumble)。其他的不清楚。
【问题讨论】:
-
当您使用 g++ 9.4 编译时,您是否还针对 ARM32 还是 64 位目标?
-
好问题。 g++ 9.4 目标是 AMD64。
-
那就是原因。
long在非 Windows 中在 64 位操作系统上是 64 位,在 32 位操作系统上是 32 位。 -
好的。那么为什么 int32_t 重载在 ARM 32 位上没有冲突呢?
-
int32_t很可能是int的 typedef,并且由于long的排名高于int,因此它不会转换为它。