繁体   English   中英

stdint 类型与原生类型:long 与 int64_t、int32_t

[英]stdint types vs native types: long vs int64_t, int32_t

uint64_t、uint32_t、long 和int(即stdint 和本机编译器类型)的类型等效性是否发生了变化。 还是我遇到了 g++ 错误?

带有 c++17 选项的 g++ 8.3 中的以下代码编译时没有错误。 架构是 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.

使用带有 c++17 选项的 g++ 9.4 编译的相同代码会产生错误,因为无法区分 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++ (mumble-mumble) 中变成了一种与 uint16_t/int16_t 不同的类型。 不确定其余的。

是的,不同的 CPU 架构有不同大小的基本类型,固定宽度的别名映射到不同的类型。 这也因操作系统而异。 不仅仅是建筑。 这是正常现象,不是错误,并且通常不会在编译器版本之间发生变化。

为了避免这个问题,要么只为固定宽度的类型提供重载,要么为每个基本类型提供重载。 不要混合它们。

在这种情况下,最好使用函数模板而不是重载:

template<class T>
void write(T value)
{
    os << value;
}

char, uint8_t, int8_t 的等效性如何?

所有这些总是不同的类型。 std::uint8_t - 当它被定义时 - 是unsigned char的别名,而std::int8_t - 当定义时 - 是signed char的别名。 这两者都与char类型不同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM