PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, November 4, 2022

[FIXED] Why visual c++ (latest) and gcc 12.1 accepted hiding this init capture for lambda, while clang 14.0.0 not? (c++20)

 November 04, 2022     c++, compiler-errors, lambda, language-lawyer     No comments   

Issue

Case 1

int main() {
    int x = 100;
    auto lamb_var = [y = x](){
                    int y = 10;
                    return y + 1;
    }; 

    assert (lamb_var() == 11);

    return 0; 
}

in https://godbolt.org/z/hPPParjnz

Both MSVC and GCC accepted shadowing the init-capture, while Clang accused y redefinition on the compound statement and throwed compiler error.

However, if we remove the init-capture and make a simple-capture, all compilers accept Shadowing:

Case 2

int main() {
    int x = 100;
    auto lamb_var = [x](){
                    int x = 10;
                    return x + 1;
    }; 

    assert (lamb_var() == 11);

    return 0; 
}

in https://godbolt.org/z/Gs4cadf5e


A simple-capture (case 2) leads to the creation of an attribute in the lambda-associated class, so shadowing should be normal.

From what I found,the expression "whose declarative region is the body of the lambda expression" of the quote below from cppreference could defend the implementation of CLANG ("redefinition"), but I'm not sure.

A capture with an initializer acts as if it declares and explicitly captures a variable declared with type auto, whose declarative region is the body of the lambda expression (that is, it is not in scope within its initializer), except that: [...]

Who is right in implementation (GCC and MSVC or Clang), and how to understand this citation of cppreference?


Related questions

Lambda capture and parameter with same name - who shadows the other? (clang vs gcc)


Solution

I think that clang is correct in rejecting snippet 1 and accepting snippet 2 because in the first case the non-static data member is named y while in the second case the non-static data member is unnamed.

Case 1

Here we consider snippet 1:

int main() {
    int x = 100;
    auto lamb_var = [y = x](){  //the data member is "named" y
                    int y = 10; //error because we're defining y for second time 
                    return y + 1;
    }; 

    assert (lamb_var() == 11);

    return 0; 
}

Now, from expr.prim.lambda#capture-6:

An init-capture without ellipsis behaves as if it declares and explicitly captures a variable of the form auto init-capture ; whose declarative region is the lambda-expression's compound-statement, except that:

(emphasis mine)

This seems to indicate that the non-static data member has a name which in your given example is y. Now, by writing int y = 10; we're providing a redefinition of the same named variable y in the same declarative region and hence the error.


Note that we will get the same error(as expected due to the reason explained above), if we replace [y=x] with [x=x] and int y =10; with int x = 10; as shown below:

int main() {
    int x = 100;
    auto lamb_var = [x = x](){  //data member "named" x
                    int x = 10; //this will give same error 
                    return x + 1;
    }; 

    assert (lamb_var() == 11);

    return 0; 
}

Case 2

Here we consider the snippet 2:

int main() {
    int x = 100;
    auto lamb_var = [x](){         //data member is unnamed
                    int x = 10;   //ok because we're defining an int variable with "name" x for the first time in this region
                    return x + 1;
    }; 

    assert (lamb_var() == 11);

    return 0; 
}

Here from expr.prim.lambda#capture-10:

For each entity captured by copy, an unnamed non-static data member is declared in the closure type. The declaration order of these members is unspecified....

(emphasis mine)

In this case, the non-static data member is unnamed and so writing int x = 10; is not a redefinition error because we're definining a variable named x for the first time in this region.



Answered By - Jason Liam
Answer Checked By - David Goodson (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing