为什么GCC优化不能使用valarrays? [英] Why does GCC optimization not work with valarrays?

查看:174
本文介绍了为什么GCC优化不能使用valarrays?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个使用valarrays的简单c ++程序:

  #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;
}



如果我像这样编译和运行:

  g ++ -O0 main.cpp&& ./a.out 

输出符合预期:

  512 256 128 

编译和运行它像这样:

  g ++ -O3 main.cpp&& ./a.out 

输出为:

  0 0 0 

code> -O1 优化参数。



GCC版本(最新在Archlinux):

  $ g ++ --version 
g ++(GCC)6.1.1 20160707

但是,如果我尝试用clang,两个

  clang ++ -std = gnu + +14 -O0 main.cpp&& ./a.out 

  clang ++ -std = gnu ++ 14 -O3 main.cpp&& ./a.out 

产生相同的正确结果:

  512 256 128 

  $ clang ++ --version 
clang version 3.8.0(tags / RELEASE_380 / final)

我也试过在Debian上使用GCC 4.9.2,其中可执行文件产生正确的结果。



这是GCC中的一个可能的错误还是我做错了什么?任何人都可以复制这个?



编辑:我设法在Mac OS上的Homebrew版本的GCC 6上重现这个问题。

解决方案

valarray auto p>

这将创建一个临时对象,然后将 operator / 应用到它:

  const auto& res(ratios_t :: value_type(256)/ a); 

libstdc ++ valarray 使用表达式模板, operator / 返回一个轻量级对象,引用原始参数并延迟评估它们。您使用 const auto& 这会导致表达式模板绑定到引用,但不会延长表达式模板引用的临时的生命周期,因此,当



如果你这么做,它会工作得很好:

  ratios_t res = ratios_t :: value_type(256)/ a; 


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;

这篇关于为什么GCC优化不能使用valarrays?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆