Влияет ли -Werror на корректность шаблона и / или SFINAE? - PullRequest
0 голосов
/ 06 декабря 2018

У меня такое ощущение, что это глупый вопрос, и я думаю, что ответом является простое "Нет", хотя я понятия не имею, как быть уверенным в этом, кроме как попросить вашей помощи ...

Влияет ли -Werror на правильность шаблона (не уверен, что является правильным термином, см. Пример ниже) и / или SFINAE?

Рассмотрим этот простой надуманный пример:

template <typename T>
void foo() {
    int a;
}

int main() {
    //int a; // error: unused variable 'a' [-Werror=unused-variable]
}

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

Почему я задаю этот вопрос: я привык компилировать с -Werror всегда, поэтому мое восприятие того, что является предупреждением и ошибкой, в некоторых отношениях немного размыто.Теперь для шаблонов и особенно для SFINAE это имеет большое значение, если что-то является просто предупреждением или действительно ошибкой.

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Хотя это во многом проблема качества реализации, -Werror действительно может (и имеет) мешать SFINAE.Вот более сложный пример для тестирования:

#include <type_traits>

template <typename T>
constexpr bool foo() {
    if (false) {
        T a;
    }
    return false;
}

template<typename T, typename = void> struct Check {};
template<typename T> struct Check<T, std::enable_if_t<foo<T>()>> {};

int main() {
    Check<int> c;
}

Строка T a; может вызвать это предупреждение (и ошибку), даже если ветвь не работает (она намеренно мертва, так что fooявляется функцией constexpr в основном независимо от T).Теперь, согласно самому стандарту, это правильно сформированная программа.

Но поскольку Clang и GCC вызывают там ошибку, и эта ошибка находится в не непосредственном контексте специализации Check, мы получаем серьезную ошибку,Несмотря на то, что согласно самому стандарту это должно просто вернуться к основному шаблону из-за сбоя замещения только в непосредственном контексте.

0 голосов
/ 06 декабря 2018

Я знаю, что компилятор должен генерировать ошибку для шаблонов, которые ошибочны для любого параметра шаблона, даже если он не создан.

Однако это не так.Если для шаблона не может быть сгенерировано никакого экземпляра, значит, программа некорректна, диагностика не требуется (1) .Таким образом, программа работает некорректно, независимо от того, получаете ли вы ошибку или она «компилируется».

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

Другими словами, -Werror может заставить компилятор отклонить корректно сформированныйпрограмма (это ее целевое назначение, в конце концов), но это будет ошибка компилятора, если она изменит семантику единицы.


(1) Цитирование C ++ 17(N4659), [temp.res] 17.6 / 8:

Программа некорректна, диагностика не требуется, если:

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