【问题标题】:Strange outputs of std::to_string in C++11C++11 中 std::to_string 的奇怪输出
【发布时间】:2018-06-08 22:22:48
【问题描述】:

我有这个 C++ 代码的小 sn-p:

#include <array>
#include <string>
#include <iostream>

int main() 
{
  std::string name = "mario";
  std::cerr << "Hello world! " + name + "\n";

  std::array<float, 4> arr = {12, 12.3, 13, 14};
  std::cerr << "first item is: " + std::to_string(arr.front()) << std::endl;
  std::cerr << "last item is: " + std::to_string(arr[-1]) << std::endl;
  return 0;
}

它编译并输出以下内容:

work ❯ c++ -std=c++11 -o hello_world hello.cpp
work ❯ ./hello_world
Hello world! mario
first item is: 12.000000
last item is: 0.000000

但是,如果我将前两行注释掉:

#include <array>
#include <string>
#include <iostream>

int main() 
{
  //std::string name = "mario";
  //std::cerr << "Hello world! " + name + "\n";

  std::array<float, 4> arr = {12, 12.3, 13, 14};
  std::cerr << "first item is: " + std::to_string(arr.front()) << std::endl;
  std::cerr << "last item is: " + std::to_string(arr[-1]) << std::endl;
  return 0;
}

然后编译并运行它。然后它输出以下内容:

work ❯ c++ -std=c++11 -o hello_world hello.cpp
work ❯ ./hello_world
first item is: 12.000000
last item is: 12.000000

我有三个问题:

  1. 为什么在第一种情况下使用arr[-1]时会得到0.000?
  2. 为什么我们在使用arr[-1]时会在第二种情况下得到12.000?
  3. 当我们注释掉前两个语句时,为什么在第二种情况下,arr[-1] 会得到不同的输出?

编辑:根据 cmets,我知道 arr[-1] 将是未定义的行为,因此在第一种情况下返回 0.000。但是,注释掉其他语句如何改变这种行为?由于我来自 Python 世界,这让我完全感到困惑。

【问题讨论】:

  • std::to_string(arr[-1]) 应该做什么?
  • 最后一个元素是back()
  • C++ 不是 Python
  • 未定义行为的魔力。
  • arr[-1] 将访问 arr[18446744073709551615] 元素,但您的数组只有 4 个元素,所以这里略有不匹配。

标签: c++ c++11 tostring stdstring stdarray


【解决方案1】:

这是因为 Undefined behavior,因为std::array::operator[] 不执行任何边界检查,并且您正在访问不存在的内容。

std::array::operator[] 返回对元素的引用 指定位置pos。不执行边界检查。

因此,无论您更改或评论什么,UB 仍然是 UB。

【讨论】:

猜你喜欢
  • 2012-11-21
  • 1970-01-01
  • 2017-11-26
  • 1970-01-01
  • 2013-11-22
  • 2021-12-03
  • 2011-06-14
  • 2017-09-15
  • 2021-05-08
相关资源
最近更新 更多