关于类成员访问表达式的一个定义规则 [英] One definition rule about class member access expression

查看:160
本文介绍了关于类成员访问表达式的一个定义规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在N4296,3.2 [basic.def.odr] p3:


变量 x ex 是由 ex - 到-rvalue转换为 x 产生一个不调用任何非平凡函数的常量表达式,如果 x 是一个对象, ex 是表达式 e 的一组潜在结果的一个元素,其中lvalue-对 e 应用到值转换,或者 e 是丢弃值表达式。


如何解释这一段?我发现了两个解释。



1从这里

<我们将这个分解为步骤:表达式中的变量`x`的出现构成一个odr使用,除非:




  1. 必须满足以下所有条件:


    1. 将左值到右值转换应用到 x 产生一个不调用任何非平凡函数的常量表达式

    2. ex 是表达式 e 的潜在结果集合中的一个元素, b>:


      1. 左值到右值转换应用于 e

      2. e 是舍弃值





      3. 和2来自cppreference http://en.cppreference.com/w/cpp/language/definition


        一个变量<$ c除非任何成立,否则在潜在求值表达式 ex 中的$ c> x




        • 将左值到右值转换应用到 x 不调用非平凡函数的表达式


        • x 是一个对象,ex是下列之一较大表达式的潜在结果 e ,其中较大的表达式是丢弃值表达式或左值到右值转换



        关于两个规则的第一个答案是,另一个是强>。哪一个是正确的?



        请将规则分成多个步骤来说明此代码:

          struct S {static const int x = 0; }; 
        extern S s; //没有定义s
        int i = s.x; //是s odr使用?是x odr使用?
        // gcc 5.1.0 is ok


        解决方案

        cppreference 是错误的;从标准中的语言(无论哪个版本)都清楚,两个子句必须保持。



        在您的示例中, s 不是常量表达式(C ++ 14:不满足出现在常量表达式中的要求),所以使用odr。



        同时, x 也使用odr,因为虽然可能在适当的上下文中的常量表达式中使用 x (例如作为 S 定义的数组) x 不是封闭表达式 sx 的潜在结果之一,这是唯一的封闭表达式丢弃值转换或左值到右值转换。



        gcc可能没有 s的定义 x ,但没有要求实施诊断每个odr违例。


        In N4296, 3.2 [basic.def.odr]p3:

        A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion to x yields a constant expression that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion is applied to e, or e is a discarded-value expression.

        How to explain this paragraph? I found two explanation.

        1 from here "Trying to understand [basic.def.odr]/2 in C++14 (N4140)"

        Let's split this into steps: The occurrence of a variable `x` in an expression `ex` constitutes an odr-use unless:

        1. Either ex is not potentially evaluated, or
        2. All of the following must be fulfilled:

          1. "applying the lvalue-to-rvalue conversion to x yields a constant expression that does not invoke any non-trivial functions" and
          2. "ex is an element of the set of potential results of an expression e" and either of the following holds:

            1. "either the lvalue-to-rvalue conversion is applied to e"
            2. "or e is a discarded-value expression"

        and 2 from cppreference http://en.cppreference.com/w/cpp/language/definition

        a variable x in a potentially-evaluated expression ex is odr-used unless any of the following is true:

        • applying lvalue-to-rvalue conversion to x yields a constant expression that doesn't invoke non-trivial functions

        • x is an object and ex is one of the potential results of a larger expression e, where that larger expression is either a discarded-value expression or an lvalue-to-rvalue conversion

        First answer about two rules is and, the other is any. Which one is right?

        Please split rules into steps to explain this code:

        struct S { static const int x = 0; };
        extern S s;// no definition of s
        int i = s.x;// is s odr-used? is x odr-used?
                    // gcc 5.1.0 is ok
        

        解决方案

        cppreference is was wrong; it is clear from the language in the standard (whichever version) that both subclauses must hold. I've corrected it.

        In your example, s is not a constant expression (C++14: does not satisfy the requirements for appearing in a constant expression) so is odr-used. The second subclause does not arise.

        Meanwhile, x is also odr-used, because although it would be possible to use x in a constant expression in an appropriate context (e.g. as an array bound within the definition of S); x is not one of the potential results of the enclosing expression s.x, which is the only enclosing expression subject to either the discarded-value transformation or the lvalue-to-rvalue conversion.

        gcc might be OK without a definition of s or x, but there's no requirement that an implementation diagnose every odr violation.

        这篇关于关于类成员访问表达式的一个定义规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆