3

The following code fails to compile in gcc 4.6.3, while it compiles flawless in clang 3.1 (I provide two versions of the class DummyMath, both exhibit the same problem):

#include <iostream>
using namespace std;

//* // To swap versions, comment the first slash.

// ===============================================
// V1
// ===============================================
template <typename T>
class DummyMath
{
public:
    T sum(T a1, T a2);
    T mult(T a1, int n);
};

template <typename T>
T DummyMath<T>::sum(T a1, T a2)
{
    return a1 + a2;
}

template <typename T>
T DummyMath<T>::mult(T a1, int n)
{
    auto x2 = [this](T a1) -> T
    {
        return sum(a1, a1); // <------- gcc will say that "sum" was not declared in this scope! 
    };

    T result = 0;
    n = n/2;
    for(int i = 0; i < n; ++i)
        result += x2(a1);
    return result;
}
/*/
// ===============================================
// V2
// ===============================================
template <typename T>
class DummyMath
{
public:
    T sum(T a1, T a2)
    {
        return a1 + a2;
    }

    T mult(T a1, int n)
    {
        auto x2 = [this](T a1) -> T {
            return sum(a1, a1);
        };

        T result = 0;
        n = n/2;
        for(int i = 0; i < n; ++i)
            result += x2(a1);
        return result;
    }
};
//*/

int main()
{
    DummyMath<float> math;
    cout << math.mult(2.f, 4) << endl;

    return 0;
}

The error is:

main.cpp:25:20: error: ‘sum’ was not declared in this scope

Both versions (V1 and V2) of class DummyMath fail in gcc, and both succeed in clang. Is that a bug in GCC?

Thanks.

3
  • 1
    If you rewrite it as something like return DummyMath<T>::sum(a1, a1); does it work? Commented Apr 15, 2013 at 4:53
  • Indeed, it works sir. Commented Apr 15, 2013 at 4:58
  • 2
    gcc4.7.2 has an internal compiler error here, which is definitely a bug. So there is probably a bug in 4.6.3 too. Commented Apr 15, 2013 at 5:07

1 Answer 1

4

This is known bug from gcc 4.7.2 (see this question). The compiler recognizes the this pointer is to be captured and the generated closure does contain a pointer for it, but that pointer does not get initialized in the closure's constructor.

You can use return this->sum(a1, a2); to get it to work. Running your example on LiveWorkSpace, shows that this is fixed for gcc >= 4.7.3, as well as Clang 3.2 and Intel 13.0.1 (i.e. printing 8 as output).

C++11 support is very much in flux, and it's best to upgrade to the latest version of your favorite compiler as soon as possible. Unfortunately, most Linux distributions ship packaged versions of gcc 4.7.2, and not yet for gcc 4.8.0. You might need to compile those from source.

Sign up to request clarification or add additional context in comments.

1 Comment

gcc 5.4 has this bug as well. Your suggested fix solves it though. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.