size_t、vector::size_type等类型定义是否保证不会绑定到char类型?

3
< p > 它绝对有可能将 typedefs 绑定到char变量上。例如,uint_least8_t很可能绑定到unsigned char,而int_least8_t绑定到signed char

标准是否保证类似的事情不会发生在size_t或类似类型上?还是至少有一种纯理论上的机会,这些类型将绑定到一些char类型,如unsigned char,甚至可能是wchar_t


еҪ“unsigned charзҡ„дҪҚж•°и¶іеӨҹж—¶пјҢе®ғе®Ңе…ЁеҸҜд»Ҙз”ЁдәҺsize_tгҖӮ - chris
那么,cout << vector.size() 可能是一个危险的操作吗?更不用说 vector<int>::size_type n; cin >> n; vector<int> t(n) 了吧? - user4385532
我想是的,如果你有一个足够奇怪的实现。 - chris
2个回答

4

我们所知道的关于std::size_t的信息如下:

类型size_t是一个实现定义的无符号整数类型,它足够大以容纳任何对象的字节数。

如果unsigned char满足这个条件,它可以被用作std::size_t

然而,这种情况纯粹是理论上的问题,因为没有一个真实的平台(据我所知)在那里unsigned char将足够宽(好吧,这是错误的),char类型被用作std::size_t或类似的类型。

如果你非常谨慎,你可以使用一元运算符+将值提升至至少int

std::cout << +vector.size();

这将打印数字,即使大小类型是字符类型也是如此。
对于读取,您可以使用类型为std :: common_type <unsigned int,std :: size_t> :: type 的变量(可能通过typedef),然后在sizeof(int)> sizeof(std :: size_t)的情况下进行边界检查。

使用std::cout时是正确的,但是使用std::cin会变得有点困难。 - user4385532
2
我不确定你的最后一段完全正确。有适用于DSP(数字信号处理器)的C实现,其中CHAR_BIT> 8;特别是,我认为存在CHAR_BIT == 32。但是,在这样的系统上,unsigned int也可能是32位,并且将是size_t的更好选择,因此没有充分的理由使size_t成为字符类型。 - Keith Thompson
有些机器的char类型肯定足够宽。编辑我来晚了... - Matteo Italia
@gaazkam 你可以开始读取类型为 std::common_type<unsigned int, std::size_t>::type 的变量。它至少和 std::size_t 一样大,至少是一个 unsigned int,然后在 sizeof(int) > sizeof(std::size_t) 的情况下进行边界检查。 :) - Baum mit Augen
@gaazkam common_type 的使用是可行的,因为 int 的转换级别比 char 高,并且对于 cin 来说, wchar 无关紧要。关于“丑陋”的部分:我想如果您想要如此谨慎,那就必须接受它。 - Baum mit Augen
显示剩余5条评论

0

文档N3337是目前免费在线获取的最接近C++11的版本。相关章节包括3.9.1 [basic.fundamental],18.2 [support.types]和18.4 [cstdint]。

除了wchar_t之外,您感兴趣的所有类型名称都需要是适当有符号性的原始整数类型的typedefsigned charunsigned char被认为是原始整数类型;普通的char则不是。 wchar_t是特殊的;在C++(而不是C)中,它是一个关键字(如int)和一个独立的原始类型。

普通的charsigned charunsigned char被认为是字符类型wchar_tchar16_tchar32_t不是字符类型(也不是整数类型)。

所以答案是,除了wchar_t之外,你提到的所有类型都可以被定义为signed charunsigned char,但不能作为普通的char

是的,这很令人困惑。这反映了与C的兼容性不同程度的纠缠历史,以及如何处理无法用ASCII表示的文本的不断变化的想法。


charsigned charunsigned charwchar_tchar16_tchar32_t都是整数类型。请参见N3337中的[basic.fundamental]/7。字符类型是整数类型的子集。 - M.M
@M.M 我认为你把integral类型和integer类型搞混了。我相信[basic.fundamental]/2和/3中列出的类型是唯一的integer类型。请注意,charwchar_tchar*_t在这些列表中并没有出现。 - zwol
@M.M. 你说得对,但这是标准中的一个错误(追溯到C++98),因为有很多地方使用“具有整数类型的积分常量表达式”这样的语言,旨在排除字符和枚举类型。例如,4.10中对空指针常量的定义:如果将[basic.fundamental]/7面值,则“具有整数类型”部分是无意义的,'\0'是C++中有效的空指针常量,但它不应该是。 - zwol
@M.M 我只能说我确信 C++ 委员会的意图是 '\0' 是一个有效的空指针常量。也许我们中的某个人应该提交一个缺陷报告。 - zwol
那是在哪里写下的? - M.M
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接