Блог пользователя nitin12384

Автор nitin12384, история, 15 месяцев назад, По-английски

Say you have a variable length array declared in a function, and you try to initialize it using memset in a lambda function, like this.

int n; cin>>n;
int cnt[n];
auto reset = [&](){
    memset(cnt, 0, sizeof(cnt));
};

It will not work correctly because sizeof(cnt) will return sizeof(int*) instead of n*sizeof(int).
That is because variable length array seems to decay to pointer when using labmda functions.

But surprisingly, this happens only in C++17, not in C++20.
In C++ 20, sizeof(cnt) will return n*sizeof(int).

Here is code demonstating this. You can try to run it in custom invocation.

Demo Code
Output in GNU G++17 7.3.0
Output in GNU G++20 11.2.0 (64 bit, winlibs)

Just be cautious while using arrays in lambda functions. I got wrong answer in a problem due to this, and it took me a lot of time to figure out that this was causing the issue.

Anyone is welcome to post comment of any related facts/insight, or maybe some explanations about why this happens, and why this doesn't happens in C++20.

  • Проголосовать: нравится
  • +10
  • Проголосовать: не нравится

»
15 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I was learning forward declaration of lambda. This is giving me runtime error. Can you help?

code
  • »
    »
    15 месяцев назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    You must include the "functional" library to declare lambda as a function<> type and define the function's body before calling it.

    #include <iostream>
    #include <functional>
    
    using namespace std;
    
    int main()
    {
        function<int(int)> get2;
        
        get2 = [&](int a)
        {
            return a;
        }; 
    
        cout << get2(3);
        return 0;
    }
    
»
15 месяцев назад, # |
  Проголосовать: нравится +27 Проголосовать: не нравится

It's not standard-related (variable length array not a part of C++ and never was). That behavior changed from GCC 10.1.