相关疑难解决方法(0)

通过C++标准的下标:legal来获取一个过去的数组元素的地址?

我已经看过它多次断言现在C++标准不允许使用以下代码:

int array[5];
int *array_begin = &array[0];
int *array_end = &array[5];
Run Code Online (Sandbox Code Playgroud)

&array[5]在这种情况下是合法的C++代码吗?

如果可能的话,我想要一个参考标准的答案.

知道它是否符合C标准也很有趣.如果它不是标准的C++,为什么决定做出从不同的治疗呢array + 5还是&array[4] + 1

c c++ standards language-lawyer

75
推荐指数
6
解决办法
6741
查看次数

Lvalues不指定C++中的对象14

我在这里使用N3936作为参考(如果任何C++ 14文本不同,请更正此问题).

在3.10 Lvalues和rvalues下,我们有:

每个表达式都属于此分类法中的基本分类之一:lvalue,xvalue或prvalue.

但是左值的定义是:

左值 [...]表示一个功能或一个对象.

在4.1 Lvalue-to-rvalue转换中,文本显示:

[...]在所有其他情况下,转换的结果根据以下规则确定:[...]否则,glvalue指示的对象中包含的值是prvalue结果.

我的问题是:在左值不指定对象的代码中会发生什么?有两个典型的例子:

例1:

int *p = nullptr;
*p;
int &q = *p;
int a = *p;
Run Code Online (Sandbox Code Playgroud)

例2:

int arr[4];
int *p = arr + 4;
*p;
int &q = *p;
std::sort(arr, &q);
Run Code Online (Sandbox Code Playgroud)

哪些行(如果有的话)格式不正确和/或导致未定义的行为?

参考实施例1:是*p左值?根据我的第一句话,它必须是.但是,我的第二个引文排除了它,因为*p没有指定一个对象.(它肯定不是xvalue或prvalue).

但是如果你将我的第二个引用解释*p为实际上是一个左值,那么它就不会被左值到右值转换规则所覆盖.您可以采用全部规则"标准未定义的任何内容是未定义的行为",但是只要没有执行左值到右值的转换,就必须允许空引用存在.

历史:此问题在DR 232中提出.在C++ 11中,DR232的分辨率确实出现了.引用N3337 Lvalue -to-rvalue转换:

如果glvalue引用的对象不是类型T的对象,并且不是从T派生的类型的对象,或者如果对象未初始化,则需要此转换的程序具有未定义的行为.

它似乎仍然允许空引用存在 - 它只清除了在一个上执行左值到右值转换的问题.也讨论了这个SO线程

DR232的分辨率不再出现在N3797或N3936中.

c++ lvalue language-lawyer c++14

6
推荐指数
1
解决办法
547
查看次数

标签 统计

c++ ×2

language-lawyer ×2

c ×1

c++14 ×1

lvalue ×1

standards ×1