c++ - &arr[size] 有效吗?

标签 c++ arrays language-lawyer undefined-behavior

假设我有一个函数,调用如下:

void mysort(int *arr, std::size_t size)
{
  std::sort(&arr[0], &arr[size]);
}

int main()
{
  int a[] = { 42, 314 };
  mysort(a, 2);
}

我的问题是:mysort(更具体地说,&arr[size])的代码是否已经定义了行为?

我知道如果替换为 arr + size 会完全有效;指针算法允许正常指向末尾。但是,我的问题具体是关于 &[] 的使用。

根据 C++11 5.2.1/1,arr[size] 等价于 *(arr + size)

引用5.3.1/1,一元*的规则:

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points. If the type of the expression is “pointer to T,” the type of the result is “T.” [ Note: a pointer to an incomplete type (other than cv void) can be dereferenced. The lvalue thus obtained can be used in limited ways (to initialize a reference, for example); this lvalue must not be converted to a prvalue, see 4.1. —end note ]

最后,5.3.1/3 给出了&的规则:

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue ... if the type of the expression is T, the result has type “pointer to T” and is a prvalue that is the address of the designated object (1.7) or a pointer to the designated function.

(我的重点和省略号)。

对此我还不能下定决心。我确信在 arr[size] 上强制进行左值到右值的转换将是未定义的。但是代码中没有发生这种转换。 arr + size 不指向对象;但是虽然上面的段落讨论了对象,但它们似乎从未明确指出对象实际存在于该位置的必要性(与 4.1/1 中的左值到右值转换不同)。

那么,问题是:mysort,它的调用方式是否有效?

(请注意,我在上面引用了 C++11,但如果在以后的标准/草案中对此进行更明确的处理,我会非常满意)。

最佳答案

这是无效的。您在问题中加粗了“结果是指代表达式指向的对象或函数的左值”。这正是问题所在。 array + size 是一个不指向对象的有效指针值。因此,您对 *(array + size) 的引用没有指定结果指的是什么,这意味着不需要 &*(array + size)给出与 array + size 相同的值。

在 C 中,这被认为是一个缺陷并已修复,因此规范现在在 &*ptr 中说,&* 都不会得到评估。 C++ 还没有收到固定的措辞。这是一个非常古老的仍然活跃的 DR 的主题:DR #232 .意图是它是有效的,就像它在 C 中一样,但标准没有这么说。

关于c++ - &arr[size] 有效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35365205/

相关文章:

c++ - 适用于 Apache Cassandra 的 DataStax C/C++ 驱动程序 : Blob Conversion (GCrypt Crypto Key) Issue

java - 正则表达式问题

c# - 如何将 COM 对象从 VBA 传递到 C++ DLL

java - 十六进制编码字符串到字节数组

c++ - 不明确的重载 - 带有参数包的部分函数模板排序

c++ - 管理琐碎类型

c++ - DLL包装器和DLL之间的区别

c++ - 需要平面表示中数组索引的算法

ios - Swift 和 JSON 只解析一个对象而不是一个数组

c++ - *&++i 会在 C++03 中导致未定义的行为吗?