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

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

我注意到我的生产 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;

            [[maybe_unused]]STR objSTR;
        };
    
    lambda( std::string{} );

    return 0;
}

编译器消息如下:

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

我知道我的结构不会初始化 'int STR::a' 但如果我现在用

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;

            [[maybe_unused]]STR objSTR;
        };
    
    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;

            [[maybe_unused]]STR objSTR{};
        };
    
    lambda( std::string{} );

    return 0;
}

如果它有任何模板特定的原因,我可以接受,但从 GCC 10.1 开始,第一个示例中没有通用 lambda 的注释! GCC 9.3 在这里行为不正确吗?

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

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

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

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

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