This is a simple c++ program using valarrays:
#include <iostream>
#include <valarray>
int main() {
using ratios_t = std::valarray<float>;
ratios_t a{0.5, 1, 2};
const auto& res ( ratios_t::value_type(256) / a );
for(const auto& r : ratios_t{res})
std::cout << r << " " << std::endl;
return 0;
}
If I compile and run it like this:
g++ -O0 main.cpp && ./a.out
The output is as expected:
512 256 128
However, if I compile and run it like this:
g++ -O3 main.cpp && ./a.out
The output is:
0 0 0
Same happens if I use -O1
optimization parameter.
GCC version is (latest in Archlinux):
$ g++ --version
g++ (GCC) 6.1.1 20160707
However, if I try with clang, both
clang++ -std=gnu++14 -O0 main.cpp && ./a.out
and
clang++ -std=gnu++14 -O3 main.cpp && ./a.out
produce the same correct result:
512 256 128
Clang version is:
$ clang++ --version
clang version 3.8.0 (tags/RELEASE_380/final)
I've also tried with GCC 4.9.2 on Debian, where executable produces the correct result.
Is this a possible bug in GCC or am I doing something wrong? Can anyone reproduce this?
EDIT: I managed to reproduce the issue also on Homebrew version of GCC 6 on Mac OS.
valarray
and auto
do not mix well.
This creates a temporary object, then applies operator/
to it:
const auto& res ( ratios_t::value_type(256) / a );
The libstdc++ valarray
uses expression templates so that operator/
returns a lightweight object that refers to the original arguments and evaluates them lazily. You use const auto&
which causes the expression template to be bound to the reference, but doesn't extend the lifetime of the temporary that the expression template refers to, so when the evaluation happens the temporary has gone out of scope, and its memory has been reused.
It will work fine if you do:
ratios_t res = ratios_t::value_type(256) / a;
Update: as of today, GCC trunk will give the expected result for this example. I've modified our valarray
expression templates to be a bit less error-prone, so that it's harder (but still not impossible) to create dangling references. The new implementation should be included in GCC 9 next year.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With