Странные выводы std :: to_string в C ++ 11 - PullRequest
0 голосов
/ 09 июня 2018

У меня есть небольшой фрагмент кода C ++:

#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. почему мы получаем 0,000 в первом случае, когда используем arr[-1]?
  2. почему мы получаем 12.000 во втором случае при использовании arr[-1]?
  3. почему мы получаем различный вывод для arr[-1] во втором случае, когда мы закомментируем первые два оператора?

Редактировать : Исходя из комментариев, я понимаю, что arr[-1] будет неопределенным поведением и, следовательно, возвращает 0,000 в первом случае.Но как комментирование других утверждений меняет это поведение?Это полностью сбивает меня с толку, так как я из мира Python.

1 Ответ

0 голосов
/ 09 июня 2018

Это связано с неопределенным поведением , так как std::array::operator[] не выполняет проверку границ, и вы получаете доступ к чему-то, чего там нет.

std::array::operator[] Возвращает ссылку на элемент в указанном месте поз.Проверка границ не выполняется.

Поэтому, независимо от того, что вы измените или прокомментируете, UB все равно будет UB.

...