Why this warning from IBM XL C/C++ compiler?

后端 未结 4 1438
感情败类
感情败类 2021-01-12 07:38

Here\'s a minimum code example that illustrates the problem:

#include 

class Thing
{
   // Non-copyable
   Thing(const Thing&);
   Thing         


        
4条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-12 07:52

    My gut feeling is that Jerry's answer is correct, but there are a few questions still.

    What is interesting is that there is a core issue covering the previous paragraph of that section (391). That issue relates to when the argument is the same class type. Specifically:

    int main () {
      show ( Thing (3) );       // not allowed under current wording
                                // but allowed with Core Issue 391
    
      show ( 3 );               // Still illegal with 391
    }
    

    The change in Core Issue 391 only affects where the rvalue temporary has the same class type. The previous wording had:

    If the initializer expression is an rvalue, with T2 a class type, and cv1 T1 is reference-compatible with cv2 T2, the reference is bound as follows:

    [...]

    The constructor that would be used to make the copy shall be callable whether or not the copy is actually done.

    That last line is what would make show(Thing(3)) illegal as per the current standard. The proposed wording for this section is:

    If the initializer expression is an rvalue, with T2 a class type, and "cv1 T1" is reference-compatible with "cv2 T2", the reference is bound to the object represented by the rvalue (see 3.10 [basic.lval]) or to a sub-object within that object.

    At this point, I considered that g++ may have updated its behaviour as per 391 but that the change accidentally included the copy-initialization case. However, that is not demonstrated by the versions of g++ that I tested with:

    class A{
    public:
      A ();
      A (int);
    private:
      A (A const &);
    };
    
    void foo (A const &);
    
    void foo ()
    {
      A a = 3 ;     // 3.2.3 (ERROR), 3.4.6(ERROR), 4.4.0(ERROR), Comeau(ERROR)
      
      foo ( 3 ) ;   // 3.2.3 (OK), 3.4.6(OK), 4.4.0(OK), Comeau(OK)
      foo ( A() );  // 3.2.3 (OK), 3.4.6(ERROR), 4.4.0(OK), Comeau(OK)
      foo ( A(3) ); // 3.2.3 (OK), 3.4.6(ERROR), 4.4.0(OK), Comeau(OK)
    }
    

    I cannot find fault in Jerry's interpretation for the foo (3) case, however, I do have doubts due to the discrepency between the different compiler behaviours.

提交回复
热议问题