#c #templates #clang #compiler-warnings #c 14
#c #шаблоны #лязг #предупреждения компилятора #c 14
Вопрос:
Почему я получаю это предупреждение от Clang? Мне кажется, что это разумное использование шаблонной константы.
warning: variable 'M_PI<int>' has internal linkage but is not defined [-Wundefined-internal]
#include <iostream>
template <typename T>
constexpr T M_PI = T(3.1415926535897932);
template <typename T>
constexpr T CalcCircumference(T d)
{
return d * M_PI<T>;
}
int main()
{
std::cout << CalcCircumference(42.0f);
}
Редактировать: по-видимому, минималистичный тестовый пример сбивает с толку некоторых. Я немного приукрасил это, чтобы, надеюсь, облегчить это.
Комментарии:
1. @hvd Этот код возвращает постоянное значение из main , так что, конечно , это бессмысленно, но становится менее бессмысленным из-за того, что он кажется достаточно простым, и все же он выдает предупреждение, и я хотел бы знать, почему.
Ответ №1:
Я думаю, вам следует просто проигнорировать предупреждение и пока вообще избегать переменных шаблонов.
Рассмотреть
template <typename T> T var = 0;
int main() { return var<int>; }
Это компилируется без предупреждений, ссылок и выполняется для возврата нуля.
template <typename T> T var = 0;
template <typename T> T func() { return var<T>; }
int main() { return func<int>(); }
Это компилируется без предупреждений, но не связывает: выдает сообщение об ошибке.
$ clang test2.cc -o test2 -std=c 1y -pedantic -Wall /tmp/test2-736968.o:test2.cc: функция int func(): ошибка: неопределенная ссылка на 'var' clang: ошибка: команда компоновщика завершилась ошибкой с кодом выхода 1 (используйте -v длясм. Вызов)
Принудительное создание явного экземпляра действительно работает:
template <typename T> T var = 0;
template int var<int>;
template <typename T> T func() { return var<T>; }
int main() { return func<int>(); }
Я бы сказал, что это показывает, что реализация переменных шаблонов в clang является неполной. Ваше использование constexpr
просто делает так, что clang обнаруживает свою собственную незавершенную реализацию.