【问题标题】:std::map implementation differs between linux and windowslinux和windows之间的std::map实现不同
【发布时间】:2017-04-08 19:41:50
【问题描述】:

以下代码在 linux 和 Visual Studio 2015 中编译后的行为有所不同。

#include <map>
#include <iostream>
using namespace std;

int main(void)
{
    map<int, int> map1;
    int keyCount = 2;

    for (int i = 0; i < keyCount; i++)
    {
        map1[i] = map1.size();
    }

for (auto value : map1) 
    {
        cout << "key: " << value.first << " value: " << value.second << endl;
    }
return 0;
}

Visual Studio 中的结果:

key: 0 value: 0
key: 1 value: 1

g++ -std=c++11 -Wall -pedantic

编译的linux中的结果
key: 0 value: 1
key: 1 value: 2

我有两个问题:

  1. 据我了解c++,VS的实现是对的。
    如果我将代码更改为:

    for (int i=0; i < keyCount; i++)
    {
        unsigned int mapSize= map1.size();
        map1[i] = mapSize; 
    }
    

那么它在两个平台上的行为都像 Visual Studio。
代码不应该总是这样吗?

2.我可以使用哪些 Visual Studio 编译器设置来确保 VS 与 Linux 编译相同?
我在 Windows 上工作,但有一个必须在 Linux 上工作的任务。

【问题讨论】:

  • 我想知道你为什么想要这样一张地图。

标签: c++ linux visual-studio-2015 stdmap


【解决方案1】:
map1[i] = map1.size();

扩展到

(map1.operator[](i)) = (map1.size());

C++ 不保证是先调用operator[] 还是size,因为它们都是赋值表达式的操作数。两个编译器都是正确的。

如果您期望一种行为或另一种行为,您应该将您的表达式拆分为两个语句。

【讨论】:

  • 不知道。我认为赋值的右侧总是首先被调用。
  • @lazytraveller 进一步扩展 ::operator=(map1.operator[](i), map1.size())。函数调用的参数彼此之间没有顺序。
  • @aschelper 如果程序的行为取决于操作数求值的(未指定)顺序,那么行为是否仍然定义(与未定义或实现定义相反)?
  • C++17 可能会改变这一点。
猜你喜欢
  • 2015-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 2010-09-30
  • 1970-01-01
  • 2010-11-18
  • 1970-01-01
相关资源
最近更新 更多