【发布时间】:2016-02-12 14:36:24
【问题描述】:
假设我有一个函数,调用如下:
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,一元*的规则:
一元
*运算符执行间接:应用它的表达式应该是一个指针 对象类型,或指向函数类型的指针,结果是引用对象的左值或函数 表达式所指向的。如果表达式的类型是“指向T的指针”,则结果的类型是“T”。 [ 注意: 指向不完整类型的指针(cvvoid除外)可以被取消引用。这样得到的左值 可以以有限的方式使用(例如,初始化引用);此左值不得转换为 prvalue,见 4.1。 ——尾注 ]
最后,5.3.1/3 给出了& 的规则:
一元
&运算符的结果是指向其操作数的指针。操作数应为左值……如果类型为 表达式为T,结果类型为“指向T”的指针,并且是一个纯右值,它是指定对象的地址 (1.7) 或指向指定函数的指针。
(我的重点和省略号)。
对此我还不能下定决心。我确信在arr[size] 上强制进行左值到右值的转换将是未定义的。但是代码中没有发生这种转换。 arr + size 不指向对象;但是虽然上面的段落讨论了对象,但它们似乎从未明确指出对象实际存在于该位置的必要性(与 4.1/1 中的左值到右值转换不同)。
所以,问题是:mysort,它的调用方式是否有效?
(请注意,我在上面引用了 C++11,但如果在以后的标准/草案中对此进行更明确的处理,我会非常满意)。
【问题讨论】:
-
不重复,@Angew 知道:相信我。
-
与可能的重复项相比,谁能告诉我这个问题的新内容是什么?在我看来,从那里复制粘贴答案也确实可以回答这个问题。
-
§6.5.3.2,第 3 段:...类似地,如果操作数是 [] 运算符的结果,则 & 运算符和 [] 所隐含的一元 * 都不会被计算结果就像删除了 & 运算符并将 [] 运算符更改为 + 运算符。否则,结果是指向其操作数指定的对象或函数的指针。似乎回答了这个问题。从提议的副本中直接复制/粘贴。
-
我的解读是
&arr[size]是 UB,因为它本质上是&(*something),其中*something是UB。但我正在等待专家确认。但受骗与此无关。 -
@Bathsheba 怎么不是重复的?
标签: c++ arrays language-lawyer undefined-behavior