&arr [size]有效吗?

Rei*_*ica 14 c++ arrays undefined-behavior language-lawyer

假设我有一个函数,就像这样:

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

int main()
{
  int a[] = { 42, 314 };
  mysort(a, 2);
}
Run Code Online (Sandbox Code Playgroud)

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

我知道如果被替换为完全有效arr + size; 指针算法允许正常指向过去.不过,我的问题是关于具体的使用&[].

Per C++ 11 5.2.1/1,arr[size]相当于*(arr + size).

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

一元运算*符执行间接:它所应用的表达式应该是指向对象类型的指针,或指向函数类型的指针,结果是引用表达式指向的对象或函数 的左值.如果表达式的类型是"指向T",则结果的类型为" T."[ 注意:可以取消引用指向不完整类型(cv void除外)的指针.由此获得的左值可以以有限的方式使用(例如,初始化参考); 这个左值不能转换为prvalue,见4.1.- 尾注 ]

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

一元运算&符的结果是指向其操作数的指针.操作数应为左值...如果表达式的类型是T,则结果具有"指向T"的类型,并且是作为指定对象(1.7)的地址的 prvalue 或指向指定函数的指针.

(强调和省略我的).

我无法对此作出决定.我确信强制进行左值到右值的转换arr[size]将是未定义的.但是代码中没有发生这样的转换.arr + size不指向一个物体; 但是,虽然上面的段落谈到了对象,但它们似乎从未明确地指出对象实际存在于该位置的必要性(与4.1/1中的左值到右值转换不同).

因此,问题是:是mysort,它被称为,有效与否?

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

小智 9

它无效.你在问题中加粗了"结果是一个左值,指的是表达式所指向的对象或函数".这正是问题所在.array + size是一个有效的指针值,不指向对象.因此,您的引用*(array + size)并未指定结果引用的内容,这意味着不需要&*(array + size)提供相同的值array + size.

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

  • @ThomasMatthews我的答案的重点是,虽然你所说的是预期的,但它不是*标准所说的. (3认同)