c++ - 为什么 C++ 数组索引值是有符号的而不是围绕 size_t 类型构建的(或者我错了)?

标签 c++ arrays language-lawyer standards size-t

我越来越难跟上不断发展的 C++ 标准,但现在对我来说很清楚的一件事是数组索引值应该是整数(不是 long longsize_t 或其他一些看起来更适合 size 的选择)。我从这个问题的答案 (Type of array index in C++) 以及成熟的 C++ 库(如 Qt)使用的实践中推测了这一点,这些库也使用简单的整数来表示大小和数组索引运算符。对我来说,棺材上的钉子是我现在从 MSVC 2017 收到大量编译器警告,指出我的 const unsigned long long(又名 const size_t) 变量在用作数组索引时被隐式转换为 const int 类型。

Mat 在上面链接的问题中给出的答案引用了 ISO C++ 标准草案 n3290如说

it shall be an integral constant expression and its value shall be greater than zero.

我没有阅读这些规范和准确解释他们语言的背景,所以可能需要澄清几点:

  • “整数常量表达式” 是否特别禁止诸如 long long 之类的东西,对我来说它是一个整数类型,只是一个更大的类型?
  • 他们所说的是否明确禁止标记为 unsigned 的类型,例如 size_t

如果我在这里看到的一切都是真的,数组索引值应该是 signed int 类型,为什么?这对我来说似乎违反直觉。规范甚至声明表达式“应大于零”,所以如果它是签名,我们就有点浪费了。当然,我们仍然可能希望以某种方式将索引与 0 进行比较,这对于 unsigned 类型来说是危险的,但是应该有更便宜的方法来解决这个只会浪费的问题单个值,而不是整个位。

此外,随着寄存器的不断扩大,一个更具前瞻性的解决方案是允许更大的索引类型(如 long long),而不是坚持使用 int无论如何在历史上都是一个有问题的类型(当处理器更改为 32 位 时更改其大小,然后当它们变为 64 位 时则不会)。我什至看到一些人在传闻中谈论 size_t,就像它被设计成一种更适合 future 使用的类型(而不仅仅是 sizeof 服务中返回的类型) > 运营商)。但当然,这可能是杜撰的。

我只是想确保我对这里的基础编程理解没有缺陷。当我看到像 ISO C++ 组这样的专家或 Qt 的工程师在做某事时,我相信他们有充分的理由!对于像数组索引这样的编程基础,我觉得我需要知道原因是什么,否则我可能会遗漏一些重要的东西。

最佳答案

查看[expr.sub]/1我们有

A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall be a glvalue of type “array of T” or a prvalue of type “pointer to T” and the other shall be a prvalue of unscoped enumeration or integral type. The result is of type “T”. The type “T” shall be a completely-defined object type.67 The expression E1[E2] is identical (by definition) to *((E1)+(E2)), except that in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise. The expression E1 is sequenced before the expression E2.

强调我的

因此,下标运算符的索引需要是无作用域的枚举或整数类型。在找[basic.fundamental]我们看到标准整数类型是 signed charshort intintlong int long long int,以及它们的无符号拷贝。

因此,任何标准整数类型都可以工作,任何其他整数类型(如 size_t)都将是用作数组索引的有效类型。提供给下标运算符的值甚至可以是负值,只要该值可以访问有效元素即可。

关于c++ - 为什么 C++ 数组索引值是有符号的而不是围绕 size_t 类型构建的(或者我错了)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51562875/

相关文章:

php - PHP 中的通配符数组循环

c++ - 根据标准,std::vector 是否受静态初始化顺序问题的影响?

c++ - 为什么string_view没有推导指南?

c++ - 模板相关的名称解析不应该找到没有链接的声明?

c# - 从 C# 调用非托管 (C++) 函数时出现 PInvoke 错误

arrays - Postgres : How to use arrays as stored procedure parameters efficiently?

javascript - 根据条件将数组元素从一个位置移动到另一个位置

c++ - 为什么 assembly 对我来说似乎不一致?

c++ - 如何将3D尺寸不固定的3D数组展平为1D数组?

c++ - std::pair 具有可比较对象和不可比较对象需要排序