GCC 9 和 GCC 10 中通用 lambda 内未初始化成员的不同注释

问题描述 投票:0回答:2

我注意到我的生产 C++17 代码中关于通用 lambda 和注释的行为不一致。我终于能够将其分解为以下最小示例。

为 x86_64 gcc 9.3 提供注释,但不为 x86_64 gcc 10.1 提供注释

#include <string>
#include <iostream>

struct STR { int a; };

int main() 
{
    auto lambda = 
        []( const auto& executionContext )
        {
            if ( !executionContext.empty() )
                return;

            STR objSTR;
            objSTR.a = 666;
            std::cout << objSTR.a;
        };
    
    lambda( std::string{} );

    return 0;
}

编译器消息如下:

<source>: In instantiation of 'main()::<lambda(const auto:1&)> [with auto:1 = std::__cxx11::basic_string<char>]':
<source>:19:31:   required from here
<source>:4:12: note: 'struct STR' has no user-provided default constructor
    4 |     struct STR { int a; };
      |            ^~~
<source>:4:22: note: and the implicitly-defined constructor does not initialize 'int STR::a'
    4 |     struct STR { int a; };
      |                      ^

这张纸条有什么用?我用 666 正确初始化了我的结构。 据我所知,这是正确的 C++ 代码,不需要任何关于可能未初始化的危险的注释/参考。

有趣的是,如果我现在将

auto
替换为
std::string
,则注释会完全消失。那么突然这里就不需要注释了?

对于 x86_64 gcc 9.3 和 x86_64 gcc 10.1 没有给出任何说明

#include <string>
#include <iostream>

struct STR { int a; };

int main() 
{
    auto lambda = 
        []( const std::string& executionContext )
        {
            if ( !executionContext.empty() )
                return;

            STR objSTR;
            objSTR.a = 666;
            std::cout << objSTR.a;
        };
    
    lambda( std::string{} );

    return 0;
}

如果我按如下方式使用值初始化,我只能删除通用 lambda 的注释:

对于 x86_64 gcc 9.3 和 x86_64 gcc 10.1 没有给出任何说明

#include <string>
#include <iostream>

struct STR { int a; };

int main() 
{
    auto lambda = 
        []( const auto& executionContext )
        {
            if ( !executionContext.empty() )
                return;

            STR objSTR{}; //FORCED to add {} to get rid of the note
            objSTR.a = 666;
            std::cout << objSTR.a;
        };
    
    lambda( std::string{} );

    return 0;
}

对我来说,当您在模板上下文(如通用 lambda)中不想使用此注释时,突然被迫对简单结构使用值初始化时,感觉就像是一个错误。事实上,该注释不再出现在 GCC 10.1 的上下文中,这一事实对我来说强调了这一论点。

具体、明确的问题是:
=> 你能确认这是 GCC 9.3 中的一个错误吗?

在线演示:https://godbolt.org/z/E7xeP91xd 标志: -Wall -Wextra -O3 -std=c++17
编译器:x86_64 gcc 9.3/x86_64 gcc 10.1

c++ gcc lambda initialization compiler-warnings
2个回答
1
投票

GCC 9.3 中关于 struct STR 中未初始化成员的注释在技术上是正确的,因为默认构造函数不会初始化 int a。

GCC 10.1 可能放宽了此检查或改进了通用 lambda 的上下文感知。使用 {} 初始化 objSTR 是确保初始化成员的好习惯。 如果该注释很烦人但无害,您可以安全地忽略它或显式初始化该结构。不同的编译器版本通常在警告和注释行为方面存在差异,这可以解释观察到的不一致情况。


0
投票

GCC 9.3 在这里行为不正确吗?我知道我的结构没有初始化

int STR::a

不,即使您不在程序中的任何地方使用未初始化的成员,编译器也可以给出诊断(包括警告)。

© www.soinside.com 2019 - 2024. All rights reserved.