dimanche 29 mai 2016

Variadic template array invokes undefined behavior

I'm trying to supply a parameter pack to initialize an array. I think it should work because:

  • I'm using sizeof... to get the size of the parameter pack
  • It's a template, and sizeof is a compile-time construct, so it should be known at compile-time, which means arr should not be a variable length array
  • I'm forwarding the arguments correctly

Yet I get garbage as output and a warning. First the code:

#include <iostream>
#include <utility>

template <typename... Args>
void foo(Args&&... args)
{
    int arr[sizeof...(Args)]{std::forward<Args>(args)()...};
    for (auto i = 0u; i < sizeof(arr); ++i)
        std::cout << arr[i];
}

int a() { return 1; }
int b() { return 2; }
int c() { return 3; }

int main()
{
    foo(a, b, c);  
}

Then the warning and output:

warning: iteration 3 invokes undefined behavior [-Waggressive-loop-optimizations]
         std::cout << arr[i];
         ~~~~~~~~~~^~~~~~~

note: within this loop
     for (auto i = 0u; i < sizeof(arr); ++i)
                       ~~^~~~~~~~~

1230-282327744327670000-133971368332712

Can anyone see my mistake?

Aucun commentaire:

Enregistrer un commentaire