Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Last minute change in Lambda syntax or gcc bug?

I use the svn-version of the gcc-4.7.0 to check out some C++11 features, e.g. Lambda Expressions. Since a couple of weeks some of my old examples including Lambdas to not compile anymore. I wonder:

  • Did I miss a last-minute change in the C++11-Lambda-spec that has been implemented in gcc-4.7.0 in the last weeks?
  • Is it a bug in gcc, that does not recognize inline-Lambdas anymore?
  • Or did I misunderstood something else with Lambda-syntax?

The problematic code seems to involve inline-Lambdas that are provided as arguments directly.

Would you say that the following code is correct C++11 code?

#include <thread>
using namespace std;

struct Image {}; // dummy

void fill(int color, const Image& image) {
} // dummy

int main() {
    int red;
    Image img;
    thread th{
        [&img](int c){ fill(c, img); },  // error?
      red };
    th.join();
}

If I change it and assign the Lambda to a variable first it works:

#include <thread>
using namespace std;

struct Image {}; // dummy
void fill(int color, const Image& image) {
} // dummy

int main() {
    int red;
    Image img;
    auto f = [&img](int c){ fill(c, img); }; // lambda
    thread th{ f, red };                     // ok now
    th.join();
}

I put an example here where both compiles with gcc-4.5 (except that it raises an exception, probably because -pthread is not linked). But as I said: In my gcc-4.7.0-svn the first variant stopped compiling a couple of weeks ago.

Update The error message seems to be a parse error:

In function 'int main()':
...:30:11: error: expected '=' before '(' token
...:30:12: error: expected primary-expression before 'int'
...:30:12: error: expected ')' before 'int'
...:30:36: error: no matching function for call to 
           'std::thread::thread(<brace-enclosed initializer list>)'
...:30:36: note: candidates are:
           ...
like image 554
towi Avatar asked Nov 10 '11 14:11

towi


1 Answers

As far as I can tell from the grammar defined in the draft n3242, this code is valid C++11. A braced_init-list is composed of a list of initializer-clause, which can be assignment-expressions or themselves braced_init_lists. An assignment-expression can be a lambda-expression, which is exactly what you have as a first element ([...](...){...}).

Therefore, surrounding the lambda with parentheses should not be required, if think you can safely file a bug report :). (Of course, this answer is based on a draft, so the possibility of a late change in the grammar is not to be excluded.)

like image 144
Luc Touraille Avatar answered Nov 10 '22 12:11

Luc Touraille