Я читаю учебник по C ++ Липпмана, где на стр. 303 они дают это:

class Account {
private:
  static constexpr int period = 30;
  double daily_tbl[period];
}

Если член используется только в контекстах, где компилятор может подставить значение члена, то инициализированная статическая константа или constexpr не требует отдельного определения. Однако, если мы используем член в контексте, в котором значение не может быть заменено, тогда должно быть определение для этого члена.

Также:

Например, если мы передаем Account :: period функции, которая принимает const int &, тогда необходимо определить период.

Поэтому я попробовал добавить такую ​​функцию:

class Account {
private:
  static constexpr int period = 30;
  double daily_tbl[period];

  void foo(const int &i) { ; }
  void bar() { foo(period); } //no error?
};

Там я добавил функцию, которая принимает const int &. Я также не добавил никакого определения для переменной периода. Но все равно я не получаю ошибки, так как они сказали, что я должен получить. Почему нет?

c++
9
user2015453 27 Янв 2013 в 16:36

1 ответ

Лучший ответ

Нарушение этого правила не требует диагностики. Таким образом, поведение фактически не определено.

Я думаю, что причина, по которой это не требуется для диагностики, заключается в том, что диагностику будет давать компоновщик. И когда компилятор оптимизирует доступы (как это, вероятно, произошло в этом случае), компоновщик больше не может заметить ничего неправильного. По-прежнему замечая эту ошибку, потребуется анализ всей программы в компоновщике, чтобы он имел доступ к исходному неоптимизированному представлению исходного кода. Это увеличивает время компиляции и требует продвинутого компоновщика и компилятора.

6
Johannes Schaub - litb 27 Янв 2013 в 18:54
1
Где определяется правило ?
 – 
Alok Save
27 Янв 2013 в 16:51
1
Не могли бы вы подробнее рассказать в своем ответе?
 – 
Alok Save
27 Янв 2013 в 16:54
1
Может актуально 9.4.2 / 4? «Должно быть ровно одно определение статического элемента данных, который используется odr (3.2) в программе; диагностика не требуется».
 – 
Andy Prowl
27 Янв 2013 в 16:59
1
Я думаю, что причина в том, что диагностику будет давать компоновщик. и когда компилятор оптимизирует доступ (как это, вероятно, произошло в его случае), компоновщик больше не может заметить ничего неправильного. все еще замечая эту ошибку, потребуется анализ всей программы, что увеличивает время компиляции и требует расширенного компоновщика и компилятора.
 – 
Johannes Schaub - litb
27 Янв 2013 в 16:59
2
Может быть, это слишком глупо, чтобы спрашивать, но почему использование константной ссылки на period классифицирует как контекст, в котором значение не может быть заменено компилятором? Похоже ли это на обоснование получения адреса инициализированного статического члена класса, что означает, что объект должен быть помещен в какое-то место в памяти, а не просто оптимизирован? Как так?
 – 
Alok Save
27 Янв 2013 в 17:10