valarray在gcc和msvc(或者Linux和Windows)中有什么不同

What are the differences of valarray in gcc and msvc (or Linux and Windows)

本文关键字:什么 Windows Linux gcc msvc 或者 valarray      更新时间:2023-10-16

我在Windows和Linux中体验到valarray的不同行为。有人知道这件事吗?或者知道去哪里看?很明显,在两个系统上工作的一个版本是正确的C++,但为什么另一个版本在Windows中工作?valarray的实现是否存在更多差异?

在MSVC/Windows上工作但不在gcc/Linux上工作的代码示例:

    valarray<signed short> myValues;
    for(size_t s = 0; s < 10; s++)
    {
        slice dataSlice(1, 1, 1);
        // on Linux, this slice operation gives me a segmentation fault
        myValues= RawData[dataSlice];
    }

我找到了它,为gcc/Linux版本修复了这样的代码:

    for(size_t s = 0; s < 10; s++)
    {
        slice dataSlice(1, 1, 1);
        valarray<signed short> myValues = RawData[dataSlice];
    }

gcc/Linux版本期望l值(myValues)已经初始化。这在MSVC/Windows上似乎没有必要。我可以在Linux上调用myValues.resize(1),它也能正常工作。

现在,有人确切地知道这些差异吗?或者互联网上的资源吗?是否存在如何使用valarray的最佳实践?

软件版本:

  • Windows 7,MS Visual Studio 2010 SP1,适用于80x86的Visual C++编译器16.00.40219.01
  • Lubuntu 14.04 64位虚拟机,GNU Make 3.81,GCC 4.8.2

谢谢大家。


更新:详细的代码示例进行编译。第一个例子给出了Linux中的分段错误,但在Windows中运行良好。

// This example compiles both on Windows with MSVC and on Linux with GCC.
// It gives a segmentation fault in Linux.
// It gives the expected output on Windows.
#include "stdafx.h"
#include <iostream>
#include <valarray>
int main(int argc, char **argv) {
  //init base data
  std::valarray<signed short> myData(10);
  for (int i = 0; i < 10; i++)
  {
    myData[i] = i;
  }
  std::valarray<signed short> myValues;
  for (int i = 0; i < 10; i++)
  {
    myValues = myData[std::slice(0, i, 1)];
    std::cout << "myValues: ";
    for (size_t k = 0; k < myValues.size(); k++)
    {  
        std::cout << myValues[k] << ",";
    }
    std::cout << std::endl;
  }
}

以下示例在Linux和Windows上运行良好。注意for循环中myValues的声明和其他初始化,就在切片完成的地方。

#include "stdafx.h"
#include <iostream>
#include <valarray>
int main(int argc, char **argv) {
  //init base data
  std::valarray<signed short> myData(10);
  for (int i = 0; i < 10; i++)
  {
    myData[i] = i;
  }
  for (int i = 0; i < 10; i++)
  {
    std::valarray<signed short> myValues = myData[std::slice(0, i, 1)];
    std::cout << "myValues: ";
    for (size_t k = 0; k < myValues.size(); k++)
    {  
        std::cout << myValues[k] << ",";
    }
    std::cout << std::endl;
  }
}

预期输出:

myValues:
myValues: 0,
myValues: 0,1,
myValues: 0,1,2,
myValues: 0,1,2,3,
myValues: 0,1,2,3,4,
myValues: 0,1,2,3,4,5,
myValues: 0,1,2,3,4,5,6,
myValues: 0,1,2,3,4,5,6,7,
myValues: 0,1,2,3,4,5,6,7,8,

valarray.assign/8:

valarray<T>& operator=(const slice_array<T>&);
valarray<T>& operator=(const gslice_array<T>&);
valarray<T>& operator=(const mask_array<T>&);
valarray<T>& operator=(const indirect_array<T>&);

需要:参数引用的数组的长度等于size()

myValues创建为大小为0的空valarray。不满足使用valarray<T>& operator=(const slice_array<T>&);的前提条件。

更换

myValues = myData[std::slice(0, i, 1)];

带有

auto s = std::slice(0, i, 1);
myValues.resize(s.size());
myValues = myData[s];

myValues = std::valarray<signed short>(myData[std::slice(0, i, 1)]);

它会起作用的。

我还不明白为什么选择slice_array<T> operator[](slice slicearr)而不是valarray<T> operator[](slice slicearr) const