Рассмотрим следующий фрагмент. Класс test
имеет константный член a
и функцию-член fun
, которая возвращает a
. Список инициализации используется для инициализации a
в конструкторе. Однако в списке инициализации лямбда используется для инициализации a
с возвращенным значением fun. Это приводит к различному поведению clang и gcc во время компиляции и выполнения, в зависимости от уровня оптимизации. Ниже приведен фрагмент кода и различные результаты компиляции и выполнения. Это ожидаемое поведение gcc и clang?
#include <iostream>
class test{
public:
const int a;
test(): a([this](){return fun();}()) {}
int fun()
{
return a;
}
};
int main()
{
auto t = test();
std::cout << t.a << '\n';
return 0;
}
Compiletime:
clang++-5.0 -std=c++17 -Wall -Wextra -Weverything
lambda_in_initializer_list.cpp:7:15: warning: lambda expressions are incompatible with C++98
[-Wc++98-compat]
test(): a([this](){return fun();}()) {}
^
warning: 'auto' type specifier is incompatible with C++98 [-Wc++98-compat]
lambda_in_initializer_list.cpp:17:5: warning: 'auto' type specifier is incompatible with C++98
[-Wc++98-compat]
auto t = test();
^~~~
3 warnings generated.
clang++-5.0 -std=c++17 -Wall -Wextra -Weverything -O1
lambda_in_initializer_list.cpp:7:15: warning: lambda expressions are incompatible with C++98
[-Wc++98-compat]
test(): a([this](){return fun();}()) {}
^
warning: 'auto' type specifier is incompatible with C++98 [-Wc++98-compat]
lambda_in_initializer_list.cpp:17:5: warning: 'auto' type specifier is incompatible with C++98
[-Wc++98-compat]
auto t = test();
^~~~
g++ -std=c++17 -Wall -Wextra -Wpedantic
No output
g++ -std=c++17 -Wall -Wextra -Wpedantic -O1
lambda_in_initializer_list.cpp: In function ‘int main()’:
lambda_in_initializer_list.cpp:18:20: warning: ‘t.test::a’ is used uninitialized in this function [-Wuninitialized]
std::cout << t.a << '\n';
~~^
Продолжительность:
clang++-5.0 -std=c++17 -Wall -Wextra -Weverything
0
clang++-5.0 -std=c++17 -Wall -Wextra -Weverything -O1
4196112
g++ -std=c++17 -Wall -Wextra -Wpedantic
Non deterministic output.
g++ -std=c++17 -Wall -Wextra -Wpedantic -O1
0