https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82222

            Bug ID: 82222
           Summary: wrong uninitialized reference in lambda capture in
                    fold expression
           Product: gcc
           Version: 7.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: benni.buch at gmail dot com
  Target Milestone: ---

int main(){
    int dummy = 0;
    [](auto& d, auto ... args){
        ([](auto ...){}(([&d](){}, args)), ...);
    }(dummy, 0, 0);
}

is a valid program, but:

$ g++ -std=c++17 -o main gcc-test.cpp 
gcc-test.cpp: In instantiation of 'main()::<lambda(auto:1&, auto:2 ...)> [with
auto:1 = int; auto:2 = {int, int}]':
gcc-test.cpp:5:15:   required from here
gcc-test.cpp:4:20: error: member 'main()::<lambda(auto:1&, auto:2 ...)> [with
auto:1 = int; auto:2 = {int, int}]::<lambda()>::<d capture>' is uninitialized
reference
   ([](auto ...){}(([&d](){}, args)), ...);
                    ^

I found this while implementing an output function:

#include <iostream>
#include <tuple>

template < typename Arg, typename ... Args >
void comma_separated_output(
    std::ostream& os,
    Arg const& arg,
    Args const& ... args
){
    std::apply([&os](auto const& ... args)mutable{
            (os << ... << args);
        }, arg);
    (std::apply([&os](auto const& ... args)mutable{
            ((os << ", ") << ... << args);
        }, args), ...);
}

int main(){
    comma_separated_output(std::cout,
        std::make_tuple(), std::make_tuple(), std::make_tuple());
}

$ g++ -std=c++17 -o main gcc-test.cpp 
gcc-test.cpp: In instantiation of 'void comma_separated_output(std::ostream&,
const Arg&, const Args& ...) [with Arg = std::tuple<>; Args = {std::tuple<>,
std::tuple<>}; std::ostream = std::basic_ostream<char>]':
gcc-test.cpp:20:64:   required from here
gcc-test.cpp:13:17: error: member 'comma_separated_output(std::ostream&, const
Arg&, const Args& ...) [with Arg = std::tuple<>; Args = {std::tuple<>,
std::tuple<>}; std::ostream = std::basic_ostream<char>]::<lambda(const auto:2&
...)>::<os capture>' is uninitialized reference
     (std::apply([&os](auto const& ... args)mutable{
                 ^

Tested with:
$ g++ --version
g++ (GCC) 7.2.1 20170911

Reply via email to