#c #compiler-errors
#c #ошибки компилятора
Вопрос:
Я пытаюсь узнать о const
constexpr
и столкнулся с ошибкой C26498 на VS2019. Однако мой пример почти такой же, как описано здесь:
constexpr int myInt();
constexpr int getMyValue();
void foo();
int main()
{
int val1 = myInt(); // C26498 warning (mark variable constexpr)
const int val2 = myInt(); // C26498 warning (mark variable constexpr)
constexpr int val3 = myInt(); // C2131 error (expression did not evaluate to a constant)
foo();
}
constexpr int myInt() { return 1; }
constexpr int getMyValue() { return 1; }
void foo() { constexpr int val0 = getMyValue(); // no C26498 }
Редактировать: В соответствии с запросом, вот список ошибок (VS2019):
Предупреждение C26498 — функция ‘myInt’ является constexpr, отметьте переменную ‘val1’ constexpr, если требуется вычисление во время компиляции (кон.5). строка 13
Предупреждение C26498 — функция ‘myInt’ является constexpr, отметьте переменную ‘val2’ constexpr, если требуется вычисление во время компиляции (кон.5). строка 14
Ошибка C2131 — выражение не было вычислено до постоянной строки 15
Ошибка сообщения была вызвана вызовом неопределенной функции или одной не объявленной строки constexpr 15
Я понимаю предупреждения для val1
и val2
, но затем, когда я использую constexpr
for val3
, я получаю сообщение об ошибке. Почему это выдает ошибку, когда почти тот же код, инкапсулированный в другую функцию ( foo()
), не выдает? Из моего (ограниченного) понимания, myInt()
также не может быть вычислено во время компиляции?
Комментарии:
1. пожалуйста, включите сообщение об ошибке компилятора в вопрос. Коды ошибок зависят от компилятора, и сообщение обычно содержит более полезную информацию
Ответ №1:
Ошибка возникает из-за того, что в момент использования (в constexpr int val3 = myInt();
строке) компилятор не имеет определения myInt()
и поэтому не может (безопасно) вывести значение константы времени компиляции.
Решение состоит в том, чтобы поместить это определение myInt
функции перед ее использованием (где у вас в настоящее время есть ее прямое объявление):
constexpr int myInt() { return 1; }
int main()
{
int val1 = myInt(); // C26498 warning (mark variable constexpr)
const int val2 = myInt(); // C26498 warning (mark variable constexpr)
constexpr int val3 = myInt(); // No error or warning!
return 0;
}
Комментарии:
1. Да, это устраняет ошибку, спасибо. Означает ли это, что в современном C стандартной практикой является размещение определений в начале файла? Кроме того, почему это работает
foo()
?2. Это работает для
foo
(в вашем коде), потому что к тому времени, когда компилятор достиг этого, он уже столкнулся с определениемmyInt
. У вас может быть как прямое объявление, так и определение, но вам нужно последнее, прежде чем пытаться использовать его вconstexpr
инструкции.3. О да, с точки зрения
foo()
,getMyValue()
уже было определено. Я пропустил это. Еще раз спасибо!
Ответ №2:
Функция должна быть определена перед ее вызовом. В большинстве случаев этого не происходит, потому что функция constexpr является «неявно» встроенной и определяется в файле ‘.h’ и поэтому включается в начало кода перед компиляцией.
Ответ №3:
Пожалуйста, попробуйте объявить myInt() перед его использованием (выше функции main()):
constexpr int myInt();
constexpr int getMyValue();
void foo();
constexpr int myInt() { return 1; }
int main()
{
int val1 = myInt(); // C26498 warning (mark variable constexpr)
const int val2 = myInt(); // C26498 warning (mark variable constexpr)
constexpr int val3 = myInt(); // C2131 error (expression did not evaluate to a constant)
}
constexpr int getMyValue() { return 1; }
void foo() { constexpr int val0 = getMyValue(); // no C26498 }
Это сработало на моем компьютере (g (MinGW.org ССАГПЗ-8.2.0-5) 8.2.0)