参考表达式的求值

发布于 2024-09-26 10:45:41 字数 751 浏览 6 评论 0原文

根据@Potatoswatter 的建议,我创建了一个新的讨论。

参考是来自 @Potatoswatter 的 此响应

给出代码片段,

int i = 3, &j = i; 
j = ++ i;

我寻求澄清的评论是这样的。 (这似乎是我对无序评估(又称序列点)的理解中一个重要的缺失部分):

@Chubsdad:尽管它是一个别名, 它的左值评估不 需要对 i 进行左值评估。 一般来说,评估一个 参考文献不需要 手头上的原始对象。有 没有理由它应该是 UB,所以它使得 感觉应该有一个容易的漏洞 或转换为不是的代码 UB。

参考文献没有告诉 编译器去看看引用的 变量并获取其左值,因为 它可能不知道变量是什么 参考。编译器计算出 参考的左值和 左值标识一个对象。如果你 想进一步辩论这个问题,请 提出一个新问题。

问题中任何可能的不明确都是“未定义行为”的一部分,我正在尝试理解 C++0x 中的“无序求值”、“序列点”等。

As per @Potatoswatter's suggestion, I have created a new discussion.

Reference is this response from @Potatoswatter

Given the code snippet,

int i = 3, &j = i; 
j = ++ i;

The comment which I seek clarity on, is this. (which seems to be an important missing piece in my understanding of the unsequenced evaluation a.k.a sequence point):

@Chubsdad: Even though it's an alias,
its glvalue evaluation does not
require a glvalue evaluation of i.
Generally speaking, evaluating a
reference does not require the
original object to be on hand.
There's
no reason it should be UB, so it makes
sense there should be an easy loophole
or transformation to code which is not
UB.

and

The reference doesn't tell the
compiler to go look at the referenced
variable and get its lvalue, because
it might not know what variable is
referenced. The compiler computes the
lvalue of the reference and that
lvalue identifies an object. If you
want to debate this further, please
open a new question.

Any possible lack of clarity in the question is part of the 'undefined behavior' I am going through trying to understand 'unsequenced evaluation', 'sequence point' etc in C++0x.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三月梨花 2024-10-03 10:45:41

想象一下

int &i = *new int;

如果您说 i 是另一个名称的别名 - 什么名称?引用可以引用对象或函数。当您说“glvalue”时,您指的是特定表达式的属性,而不是对象的属性。

int i = 0;
int &ri = i;

现在,i 是一个左值表达式,ri 也是一个左值表达式(都是语法类别id-expression)。它们命名(通过名称查找找到)一个引用和一个int变量。

如果您现在确定 ri 情况的对象标识,则需要获取引用并使表达式引用其初始化所用的对象。这称为左值评估,因为您确定左值(即指示对象)的属性。

您需要对 i 情况执行相同的操作。即,您找出左值表达式 i 引用的对象。因此,ri 的泛左值评估与 i 的泛左值评估不同,尽管两者产生相同的结果。

右值求值意味着获取左值并将左值应用到右值转换。换句话说,读取一个值。

Imagine the following

int &i = *new int;

If you say that i is an alias for another name - what name? A reference either references an object or function. When you say "glvalue", you refer to a property of a particular expression, not to a property of an object.

int i = 0;
int &ri = i;

Now, i is an lvalue expression and ri is an lvalue expression too (both of the syntactic category id-expression). They name (as found by name-lookup) a reference and an int variable.

If you now determine the object identity for the ri case, you need to take the reference and make the expression refer to the object it was initialized with. This is called an lvalue evaluation because you determine the property of an lvalue (i.e the referent).

You need to do the same for the i case. I.e you figure out to what object the lvalue expression i refers to. A glvalue evaluation of ri thus is different than glvalue evaluation of i, despite both of them yielding the same result.

Rvalue evaluation means to take an lvalue and apply the lvalue to rvalue conversion. In other words, to read a value.

流心雨 2024-10-03 10:45:41

从概念上讲,C++ 中的引用是某个对象的别名或替代名称。当涉及引用时,这个概念应该指导您解释语言规则。

本质上有两种实现 C++ 引用的方法:

  1. 作为编译器符号表中的注释。仅当引用仅绑定到一个对象时,这才有可能,但它也最接近引用的概念。 IMO,大多数编译器在可能的情况下都会使用这种技术,例如此处提供的示例。
  2. 作为在每次操作时自动取消引用的指针。这是后备解决方案,因为它与引用概念不匹配,但它确实使实现引用类型函数参数变得更容易,而不必严重更改 ABI。

在所提供的示例中,永远不可能存在未绑定到对象 i 的引用 j,因此编译器很可能会使用符号表实现参考注解方法。这意味着,在声明 ij 后,它们可以在代码中互换使用,而不会对生成的代码或行为是否正确的问题产生任何影响。定义的。

Conceptually, a reference in C++ is an alias, or alternative name, for some object. It is this concept that should guide you in the interpretation of the language rules when references are involved.

There are essentially two ways of implementing C++ references:

  1. As an annotation in the symbol-table of the compiler. This is only possible if the reference is only ever bound to one object, but it also stays closest to the concept of a reference. IMO, most compilers use this technique when possible, such as in the example presented here.
  2. As a pointer that gets automatically dereferenced on every operation. This is the fall-back solution, as it does not match the reference concept, but it does make it easier to implement reference-type function parameters without having to severely change the ABI.

In the presented example, there is never a way there can be a reference j that is not bound to the object i, so the compiler will most likely use the symbol-table annotation method of implementing the reference. This means that, after the declaration of both i and j, they can be used interchangeably in the code without any effect on the generated code or on the question if the behaviour is defined.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文