1 Reply Latest reply: Apr 2, 2014 12:22 PM by Steve.Clamage-Oracle RSS

    12.4 beta: private copy constructor in base class required to be called from temporary reference when -g option used

    jthackray

      Hi,

       

      We've got an abstract base class (StringBase) which various types of strings inherit from. The copy constructor for this base class is private, since we don't want to allow copying when this class shouldn't be directly instantiated. A number of our methods take specify the base class as a reference, but take a derived class temporary as a default argument (see code appended).

       

      This worked fine in 12.3, but in 12.4 beta, this now says:

         Error: StringBase::StringBase(const StringBase&) is not accessible from __dflt_argA().

       

      This works fine in clang and gcc, and indeed, this GNU document says it was a bug which was fixed in gcc 4.3.0:

          Copy constructor access check while initializing a reference

      which references http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#391


      It only appears to error when the "-g" option is used, however, which doesn't seem right, and compiles fine if the "-g" option is removed, which makes me think it's a bug. Presumably the optimizer is eliding the copy when not using -g, but it's left in for debug mode, causing the compile error?


      Many thanks,

      Jonathan.


      $ clang++ -std=c++11 defaultarg.cpp

      $ g++ -std=c++11 defaultarg.cpp

      $ /opt/SolarisStudio12.4-beta_mar14-solaris-x86/bin/CC -c defaultarg.cpp

      $ /opt/SolarisStudio12.4-beta_mar14-solaris-x86/bin/CC -g -c defaultarg.cpp

      "defaultarg.cpp", line 6: Error: StringBase::StringBase(const StringBase&) is not accessible from __dflt_argA().

      1 Error(s) detected.


      $ cat defaultarg.cpp

      #include "stringbase.h"

      #include "conststring.h"

       

      static const ConstString S_DEFAULT("default value");

       

      void SomeMethod( const StringBase& str = S_DEFAULT )

      {

         (void) str;

      }

       

      int main( void )

      {

         SomeMethod();

      }


      $ cat stringbase.h

      #ifndef STRINGBASE_H

      #define STRINGBASE_H

       

      class StringBase

      {

      protected:

         StringBase() {}

       

      private:

         StringBase( const StringBase& );

      };

       

      #endif

       

      $ cat conststring.h

      #ifndef CONSTSTRING_H

      #define CONSTSTRING_H

       

      #include "stringbase.h"

       

      class ConstString : public StringBase

      {

      public:

         ConstString() {}

         ConstString( const char* ) {}

         ConstString( const ConstString& );

      };

       

      #endif