为什么这个STL映射的项在GCC 4.5.1中没有被初始化?
Why are entries of this STL map not being initialized in GCC 4.5.1?
代码节选:
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-初始化对象。而变量的默认值包含在:
对default-initialize类型为T的对象意味着:
-如果T是非pod类类型(第9条),则调用T的默认构造函数(和如果T没有可访问的默认构造函数,则初始化是病态的);
如果T是数组类型,则每个元素默认初始化;
- ,否则为零初始化。
最后一种情况适用于这里的代码
正如人们所期望的那样,代码摘录是实际情况的简化版本。结果是在映射上使用了find命令,因此实际上调用的是map.find(1)->second
,而不是简单地调用map[1]
。这解释了未定义的行为。
- 初始化迭代器错误 C++ 在 GCC 编译器中
- 为什么 gcc 会给我可能未初始化的警告 deque::insert 带有过滤范围
- GCC 匿名是未初始化的
- 为什么数组的 GCC 聚合初始化首先用零填充整个事物,包括非零元素?
- 为什么 gcc 警告只针对统一初始化缩小转换范围?
- 不可复制类数据成员的统一初始化导致gcc错误
- 如何在macOS中的旧扩展clang和gcc编译器中初始化数组和向量
- 你能初始化unique_ptrs "static const vectors"吗?(C++17 与 GCC 7.3)
- 如何实现使用 gcc-4.4 编译的大向量初始化?
- thread_local静态成员模板定义:初始化失败,GCC
- 初始化不可移动对象数组:为什么这样的代码无法在 GCC 上编译?
- 使用GCC 4.8构建错误:数组用作初始化器
- 为什么 GCC 6.3 在没有显式 C++11 支持的情况下编译此大括号初始化列表代码
- C++指向成员的指针的类内初始化会使 MSVC 失败(但 GCC/Clang 工作)
- 告诉 GCC 假设对象已初始化
- GCC缺少优化CTOR初始化器列表的机会
- 与lambda一起使用虚拟继承在初始化列表中捕获此问题的GCC错误
- GCC允许允许非初始化的ConstexPR
- 没有临时数组的列表初始化 - 在 GCC 中不起作用
- std::make_shared是否执行值初始化(GCC和clang不同意)