Ответ 1
Это не похоже на правильную оптимизацию в соответствии с стандартным разделом проекта С++ 11 14.8
[temp.fct.spec] говорит (выделение мое в будущее):
Каждая специализированная функция шаблона, созданная из шаблона , имеет его собственная копия любой статической переменной. [Пример:
template<class T> void f(T* p) { static T s; }; void g(int a, char* b) { f(&a); // calls f<int>(int*) f(&b); // calls f<char*>(char**) }
Здесь f (int *) имеет статическую переменную s типа int и f (char **) имеет статическую переменную s типа char *. -end пример]
Так как ваш адрес переменной, складывающей их, влияет на наблюдаемое поведение, которое нарушает правило as-if.
T.C. указывает, что /opt:noicf
предотвращает несоответствие поведения.
Мэтт Макнабб указывает, что в документации OPT (Оптимизация) содержится следующее примечание:
Потому что /OPT: ICF может привести к тому, что тот же адрес будет назначен различные функции или члены данных только для чтения (константные переменные скомпилированный с использованием /Gy ), он может сломать программу, которая зависит от уникальной адреса для функций или только для чтения данных. Для большего информацию см. в разделе /Gy (Включить привязку к функциональному уровню).
Это говорит о том, что это может быть преднамеренное несоответствие поведения. Ben Voigt говорит, что комментарий теперь перемещен в чат, что это действительно означает, что оптимизация может быть несоответствующей, но эти точки являются спорными.
Пользователь usr связан с Сообщение MS: Представляем '/Gw Compiler Switch и он говорит:
Обратите внимание, что оптимизация ICF применяется только для идентичных COMDAT, где их адрес не принят, и они доступны только для чтения. Если данные не принимаются по адресу, а затем уникальность адресации ICF не приведет к какой-либо заметной разнице, поэтому она действительна и соответствует стандарту.
и более поздний комментарий говорит:
Несмотря на то, что на нем есть полностью стандартная жалоба, когда в сочетании с /Gy потенциально нарушение поведения может привести.
Из того, что я могу сказать для /Gy
для создания константных переменных, необходимо использовать __declspec (selectany), но это может быть более ясным в документации.
Как минимум мы видим, что /Gw
не должно вводить несоответствующее поведение, но /Gy
в комбинации с /Gw
может.