C ++ O2 Утечка памяти при использовании константной ссылки на литерал в классе - PullRequest
3 голосов
/ 26 января 2020

Когда я реализовывал программу, я обнаружил, что моя программа ведет себя по-разному при переключении с -g на -O2 в g ++ или clang ++.

Упрощенный код:

#include <cstdint>
#include <iostream>
class A {
 public:
  explicit A(const int64_t &zero_);
  const int64_t& zero;
};
A::A(const int64_t &zero_):
  zero(zero_) {
  std::cout << "zero=" << zero << std::endl;
}
int main() {
  A st(0);
  size_t p;
  std::cin >> p;
  std::cout << "zero=" << st.zero << std::endl;
}

Предположим, что стандартный ввод равен 1, а исключенный вывод (в последней строке) равен нулю = 0, поскольку переменная zero является константной ссылкой.

При компиляции с g++ -g -o b.o b.cc программа ведет себя нормально.

Однако при компиляции с g++ -O2 -o b.o b.cc вывод будет zero=1

Фактически, он выводит значение p.

Это ошибка или ожидаемое поведение?

протестировано на Debian10 amd64

1 Ответ

10 голосов
/ 26 января 2020

A::zero является висячей ссылкой и, следовательно, UB.

Когда вы создаете st, создается временная переменная для передачи параметра. Это временное значение выходит за рамки видимости в конце оператора, но st.zero все еще ссылается на него. Поэтому при его использовании происходят загадочные вещи.

Разница между -g и -O2 случайна. С UB могут происходить разные вещи в зависимости от конкретных обстоятельств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...