为何size_t与uint64_t长度均为8字节但std::is_same_v判定不相等?
问题
在Apple clang 14.0.0(目标平台arm64-apple-darwin21.6.0)编译环境下运行以下C++代码:
#include <iostream> #include <type_traits> int main() { std::cout << "sizeof(size_t): " << sizeof(size_t) << std::endl; std::cout << "sizeof(uint64_t): " << sizeof(uint64_t) << std::endl; if constexpr (std::is_same_v<size_t, uint64_t>) { std::cout << "size_t == uint64_t" << std::endl; } else { std::cout << "size_t != uint64_t" << std::endl; } }
运行结果为:
sizeof(size_t): 8 sizeof(uint64_t): 8 size_t != uint64_t
即size_t与uint64_t的字节长度均为8,但std::is_same_v判定二者类型不相等。请问该现象的原因是什么?C++标准中是否有相关提及?
现象原因
这是因为**size_t和uint64_t是不同的类型别名**,即使它们的底层基础类型相同、占用内存大小一致,C++类型系统仍会将它们视为不同的类型。
在苹果arm64平台上,size_t通常被定义为unsigned long的别名,而uint64_t则是unsigned long long的别名——这两个基础类型在该平台上都是8字节,但属于不同的原生类型,因此它们的别名自然会被判定为不同类型。
C++标准相关规定
C++标准对这两个类型的定义有明确区分:
size_t:是一个无符号整数类型,其大小足以容纳任何对象的字节大小。标准仅要求它是满足条件的最小无符号整数类型,具体对应哪个原生无符号类型由实现决定(可以是unsigned int、unsigned long或unsigned long long等)。uint64_t:属于<cstdint>中定义的固定宽度无符号整数类型,标准明确要求它必须是恰好64位的无符号整数类型,若平台支持则必须提供该类型。
标准并未要求size_t必须与某个固定宽度整数类型等价,它的定义更偏向适配平台内存寻址需求,而uint64_t则是明确的64位无符号类型。因此即使在某些平台上二者大小相同,它们的类型身份依然是独立的。
内容的提问来源于stack exchange,提问作者segfault
相关产品推荐
相关产品推荐

