C++ type traits compilation problem with gcc

Solution Verified - Updated -

Environment

  • Red Hat Enterprise Linux 5
  • gcc 4.1.2

Issue

Compilation of C++ code fails with the following:

/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/ios_base.h: In copy constructor ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/ios_base.h:779: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/iosfwd:55: error: within this context
ostream.cpp: In copy constructor ‘MyOutputStream::MyOutputStream(const MyOutputStream&)’:
ostream.cpp:29: note: synthesized method ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’ first required here 
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/streambuf: In copy constructor ‘MyStreamBuf::MyStreamBuf(const MyStreamBuf&)’:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/streambuf:781: error: ‘std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]’ is private
ostream.cpp:8: error: within this context
ostream.cpp: In copy constructor ‘MyOutputStream::MyOutputStream(const MyOutputStream&)’:
ostream.cpp:29: note: synthesized method ‘MyStreamBuf::MyStreamBuf(const MyStreamBuf&)’ first required here 
ostream.cpp: In copy constructor ‘MsgParam::MsgParam(const MsgParam&)’:
ostream.cpp:54: note: synthesized method ‘MyOutputStream::MyOutputStream(const MyOutputStream&)’ first required here 
ostream.cpp: In function ‘int main(int, char**)’:
ostream.cpp:76: note: synthesized method ‘MsgParam::MsgParam(const MsgParam&)’ first required here 

Resolution

Use gcc 4.4 or later

Root Cause

  • This specific test case is relying on a C++ feature (support for type traits) that was only implemented in a later version of gcc.

  • Specifically this was implemented between gcc 4.2 and 4.3 with the following commit: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26099

Diagnostic Steps

A small example of C++ code showing the issue:

#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <string>

static const char * const FOO = "foo";

class MyStreamBuf : public std::streambuf {
    public:
        MyStreamBuf(char* pBuffer, size_t size) : m_pBuffer(pBuffer),
                              m_size(size) {
            setp(m_pBuffer, m_pBuffer + m_size);
        }
        MyStreamBuf(size_t size = 64) : m_pBuffer(new char[size]),
                            m_size(size) {
            setp(m_pBuffer, m_pBuffer + m_size);
        }
        const char* str() {
            return m_pBuffer;
        }
    private:
        char* m_pBuffer;
        size_t m_size;
};

class MyOutputStream : private std::ostream {
    public:
        MyOutputStream(char *buf, size_t size) : std::ios(0), 
                               std::ostream(__null),
                               msb(buf, size) {
            std::ostream::rdbuf(&msb);
        }

        MyOutputStream(size_t size = 64) : std::ios(0),
                             std::ostream(__null),
                             msb(size) {
            std::ostream::rdbuf(&msb);
        }
        const char* str() {
            return msb.str();
        }

    private:
        MyStreamBuf msb;
}; 

class MsgParam
{
    public:
        template <class T> MsgParam(T i_param): m_params(128) {
            m_params << i_param;
        }

        MsgParam& operator+(const MsgParam& i_msgParam);
        operator const char*() { return getParams(); }
        const char* getParams() {
            m_paramStr = m_params.str();
            return m_paramStr.c_str();
        }
    private:
        MyOutputStream m_params;
        std::string m_paramStr;
};


int main (int argc, char *argv[]) {
    int ret = 0;
    std::cout << MsgParam(FOO) + MsgParam(FOO);
    std::cout << "ret :" << ret << "end\n";
    return 0;
}
  • Component
  • gcc

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Comments