c++compiler-errorsgcc4.8cray

gcc error when declaring reference to reference type


In the OpenCV library there is a

typedef const _InputArray& InputArray;

In our code we have the following function definition:

void wimshow(const String& winName, InputArray &img) {

When compiling this the following error occurs:

error: cannot declare reference to 'cv::InputArray {aka const class cv::_InputArray&}' void wimshow(const String& winName, InputArray &img) {

The weird thing is that this error only occurs using GCC 4.8.1 in the Cray environment. Compiling in a normal Linux environment with GCC 4.8.1 works without errors.
At first glance I would say that a reference to a reference type is not very meaningful anyway but I am curious about what could cause the different compiler behavior!?


Solution

  • This appears to be a C++03/C++11 difference.

    In C++11, the extra & (and the const, incidentally) are supposed to be ignored:

    [C++11: 8.3.2/6]: If a typedef (7.1.3), a type template-parameter (14.3.1), or a decltype-specifier (7.1.6.2) denotes a type TR that is a reference to a type T, an attempt to create the type “lvalue reference to cv TR” creates the type “lvalue reference to T, while an attempt to create the type “rvalue reference to cv TR” creates the type TR.

    [ Example:

    int i;
    typedef int& LRI;
    typedef int&& RRI;
    LRI& r1 = i;           // r1 has the type int&
    const LRI& r2 = i;     // r2 has the type int&
    const LRI&& r3 = i;    // r3 has the type int&
    RRI& r4 = i;           // r4 has the type int&
    RRI&& r5 = 5;          // r5 has the type int&&
    decltype(r2)& r6 = i;  // r6 has the type int&
    decltype(r2)&& r7 = i; // r7 has the type int&
    

    —end example ]

    The pertinent example here is r1; although typedef int& LRI isn't precisely like your typedef, the example is equivalent due to the following passage having already dropped your const:

    [C++11: 8.3.2/1]: [..] Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef (7.1.3) or of a template type argument (14.3), in which case the cv-qualifiers are ignored. [..]

    However, the [C++11: 8.3.2/6] wording does not exist in C++03! In fact, we can compare behaviours between the two languages with the following example program:

    struct T1 {};
    
    typedef T1& T2;
    
    int main()
    {
        T1 x;
        T2& t = x;
    }
    

    (ignoring warnings about unused variables)

    So, check your compilation flags on each platform to ensure that you're using the same language on both. It may be that the default on the Cray is C++03, but the default on your platform is C++11. Use the -std=c++03/-std=c++11 flag to state which to use explicitly.