C++ 输入流:Solaris 与 Linux 中的操作顺序
C++ Input stream: operation order in Solaris vs. Linux
我有一个非常简单的测试程序,它使用istringstreams从std::string中读取整数。 代码为:
std::map<int, int> imap;
int idx, value;
std::string str("1 2 3 4 5 6 7 8");
istringstream is(str);
while(is >> idx >> imap[idx]){
cout << idx << " " << imap[idx] << endl;
}
cout << endl;
std::map<int, int>::iterator itr;
for(itr = imap.begin(); itr != imap.end(); itr++){
cout << itr->first << " " << itr->second << endl;
}
当我在 Solaris 10 上运行它时,它会产生以下输出:
1 2
3 4
5 6
7 8
1 2
3 4
5 6
7 8
但是,当我在 CentOS 7 下运行它时,我得到:
1 0
3 0
5 0
7 0
1 4
3 6
5 8
7 0
4204240 2
有谁知道为什么在Linux下和在Solaris下会有所不同? 显然是在读取地图的索引之前将值读入地图,但我不知道为什么。 我可以通过稍微更改代码来使其在 Linux 下工作:
std::map<int, int> imap;
int idx, value;
std::string str("1 2 3 4 5 6 7 8");
istringstream is(str);
while(is >> idx >> value){
imap[idx] = value;
cout << idx << " " << imap[idx] << endl;
}
std::map<int, int>::iterator itr;
for(itr = imap.begin(); itr != imap.end(); itr++){
cout << itr->first << " " << itr->second << endl;
}
我知道这是一个有效的修复,但我周围的人想知道为什么它不同。 我们正在从Solaris迁移到Linux,当这样的事情出现时,他们想知道为什么。我不知道为什么,所以我在寻求指导。
is >> idx >> imap[idx]
此表达式等效于
operator>>(operator>>(is, idx), imap.operator[](idx))
同一函数的参数的求值相对于彼此是无序的;可以首先计算operator>>(is, idx)
或imap.operator[](idx)
(即,可以首先计算is >> idx
或imap[idx]
)。如果首先评估后者,则结果是一个左值,指的是对应于映射中idx
的旧值的值;第二次读取将覆盖的是该值,而不是对应于idx
新值的值。
修改后的代码通过确保在访问imap[idx]
之前读取idx
来解决此问题。
相关文章:
- 标记为 std::memory_order_seq_cst 的单个原子操作是否会在所有位置触发顺序一致性?
- C++和PEMDAS的优先顺序/操作?
- 内存排序或读取-修改-写入操作,仅(读/写)内存顺序
- 如果 RMW 操作没有任何变化,是否可以针对所有内存顺序对其进行优化
- MPI 归约操作中的求和顺序
- 操作顺序以最大限度地提高精度
- 在进行顺序计算时保持操作顺序
- 编译器是否会简化按顺序执行多次的操作
- 在C++中,当表达式涉及对象时,将表达式赋值到对象中时,是否有定义的操作顺序?
- C 操作顺序和模量
- C 的操作顺序用于初始化数组大小
- 访问类成员的C++操作顺序
- C++ 输入流:Solaris 与 Linux 中的操作顺序
- C++:循环增量部分的操作顺序
- 循环与操作顺序
- 这里的具体操作顺序是什么?
- if 表达式中的操作顺序是否更改
- 使用Spirit的语义操作顺序(参考Phoenix)
- 操作顺序不正确?(C++)
- C预处理器和操作顺序