为什么这个STL映射的项在GCC 4.5.1中没有被初始化?

Why are entries of this STL map not being initialized in GCC 4.5.1?

本文关键字:初始化 GCC STL 映射 为什么      更新时间:2023-10-16

代码节选:

std::map<double, double> temp;
temp[0] = .1;
cout << temp[1] << endl;
// result varies based on compiler

我正在使用GCC版本4.4.1进行编译,我从temp[1]获得0的值,正如我所期望的那样。我的同事正在编译GCC 4.5.1版本。在调试模式下(带有-g标志),他得到1000。当编译释放模式(-O2标志)时,他得到0

我的想法是,这种类型的问题通常出现在未初始化的变量,除了映射应该调用其元素的默认构造函数,基于这个问题和其他几个类似的问题。

而且, c++标准库 by Josuttis声明

如果使用键作为索引,而该键还不存在任何元素,则获取一个新元素自动插入到地图中。新元素的值为由其类型的默认构造函数初始化。

为什么在GCC 4.5.1调试模式下map中的元素没有被初始化?是我没有正确理解别人对这种行为的看法吗?新元素的默认构造是不是不一定是标准的一部分?或者这可能是编译器中的一个实际错误?

它应该像你说的那样工作(print 0),事实上在g++ 4.5.2中,它用-g, -O2或两者都打印0。如果它没有打印0,那么几乎可以肯定这是一个库错误(或者你的同事的程序已经有未定义的行为,在这种情况下,所有的猜测都是无效的(TM))。

根据c++标准,保证初始化为0

参考:

C++03标准:

23.3.1.2地图元素访问 [lib.map.access]

T& operator[](const key_type& x);

Returns:(*((insert(make_pair(x, T()))).first)).second.

T() default-初始化对象。而变量的默认值包含在:

C++03标准8.5/5:

default-initialize类型为T的对象意味着:
-如果T是非pod类类型(第9条),则调用T的默认构造函数(和如果T没有可访问的默认构造函数,则初始化是病态的);
如果T是数组类型,则每个元素默认初始化;
- ,否则为零初始化。

最后一种情况适用于这里的代码

正如人们所期望的那样,代码摘录是实际情况的简化版本。结果是在映射上使用了find命令,因此实际上调用的是map.find(1)->second,而不是简单地调用map[1]。这解释了未定义的行为。