Что такое ошибка «необъявленный идентификатор» и как ее исправить?

Что такое необъявленные ошибки идентификатора? Каковы общие причины и как их исправить?

Примеры текстов ошибок:

  • Для компилятора Visual Studio: error C2065: 'cout' : undeclared identifier
  • Для компилятора GCC: 'cout' undeclared (first use in this function)

person sashoalm    schedule 05.03.2014    source источник
comment
Очень распространенный случай - включение <iostream> и попытка использовать std::string без включения <string>. Возможно, стоит упомянуть.   -  person πάντα ῥεῖ    schedule 05.03.2014


Ответы (13)


Чаще всего они возникают из-за того, что забыли включить заголовочный файл, содержащий объявление функции, например, эта программа выдаст ошибку «необъявленный идентификатор»:

Отсутствует заголовок

int main() {
    std::cout << "Hello world!" << std::endl;
    return 0;
}

Чтобы исправить это, мы должны включить заголовок:

#include <iostream>
int main() {
    std::cout << "Hello world!" << std::endl;
    return 0;
}

Если вы написали заголовок и включили его правильно, он может содержать неправильный include guard.

Чтобы узнать больше, см. http://msdn.microsoft.com/en-us/library/aa229215(v=vs.60).aspx.

Переменная с ошибкой

Другой распространенный источник ошибки новичков возникает, когда вы неправильно написали переменную:

int main() {
    int aComplicatedName;
    AComplicatedName = 1;  /* mind the uppercase A */
    return 0;
}

Неправильный объем

Например, этот код выдаст ошибку, потому что вам нужно использовать std::string:

#include <string>

int main() {
    std::string s1 = "Hello"; // Correct.
    string s2 = "world"; // WRONG - would give error.
}

Использовать перед декларацией

void f() { g(); }
void g() { }

g не был заявлен до его первого использования. Чтобы исправить это, переместите определение g перед f:

void g() { }
void f() { g(); }

Или добавьте объявление g перед f:

void g(); // declaration
void f() { g(); }
void g() { } // definition

stdafx.h не на вершине (специфично для VS)

Это специфично для Visual Studio. В VS вам нужно добавить #include "stdafx.h" перед любым кодом. Код до того, как он игнорируется компилятором, поэтому, если у вас есть это:

#include <iostream>
#include "stdafx.h"

#include <iostream> будет проигнорирован. Вам нужно переместить его ниже:

#include "stdafx.h"
#include <iostream>

Не стесняйтесь редактировать этот ответ.

person Community    schedule 05.03.2014
comment
люди не должны редактировать другие ответы, просто исправьте его, если он неправильный, или сделайте его лучше ..., но не стесняйтесь добавлять ответ, содержащий что-то еще, и вы можете включить их в свой ответ и упомянуть, что эта часть из xxx - person Robert; 11.06.2016
comment
Я просто потратил пару часов, глядя на аналогичную проблему, и в моем случае это было связано с неправильной защитой жатки. - person Jad; 13.10.2016
comment
Еще один сложный случай, который приводит к этой ошибке: stackoverflow.com/a/6592617/6165833 - person ymoreau; 01.08.2017
comment
Еще одна вещь, на которую стоит обратить внимание, - это перекрестные ссылки. - person enkara; 06.02.2018

Рассмотрим похожую ситуацию в разговоре. Представьте, что ваш друг говорит вам: «Боб приходит на ужин», а вы понятия не имеете, кто такой Боб. Вы запутаетесь, правда? Вашему другу следовало сказать: «У меня есть коллега по работе, которого зовут Боб. Боб приходит на ужин». Теперь Боб объявлен, и вы знаете, о чем говорит ваш друг.

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

Если вы получаете такую ​​ошибку в C или C ++, это означает, что вы не сообщили компилятору о том, что пытаетесь использовать. Объявления часто встречаются в файлах заголовков, поэтому это, вероятно, означает, что вы не включили соответствующий заголовок. Конечно, может случиться так, что вы просто не забыли объявить сущность вообще.

Некоторые компиляторы выдают более конкретные ошибки в зависимости от контекста. Например, попытка скомпилировать X x;, где тип X не был объявлен с помощью clang, сообщит вам «неизвестное имя типа X». Это гораздо полезнее, потому что вы знаете, что он пытается интерпретировать X как тип. Однако, если у вас есть int x = y;, где y еще не объявлен, он сообщит вам "использование необъявленного идентификатора y", потому что есть некоторая двусмысленность в отношении того, что именно y может представлять.

person Joseph Mansfield    schedule 05.03.2014

В C и C ++ все имена должны быть объявлены до их использования. Если вы попытаетесь использовать имя переменной или функции, которая не была объявлена, вы получите ошибку «необъявленный идентификатор».

Однако функции - это особый случай в C (и только в C), поскольку вам не нужно сначала объявлять их. Компилятор C предположит, что функция существует с таким количеством и типом аргументов, как в вызове. Если фактическое определение функции не совпадает, вы получите еще одну ошибку. Этот особый случай для функций не существует в C ++.

Чтобы исправить ошибки такого рода, убедитесь, что функции и переменные объявлены до их использования. В случае printf вам необходимо включить файл заголовка <stdio.h> (или <cstdio> в C ++).

Для стандартных функций я рекомендую вам проверить, например, этот справочный сайт и выполните поиск функций, которые хотите использовать. В документации для каждой функции указано, какой файл заголовка вам нужен.

person Some programmer dude    schedule 05.03.2014

У меня была такая же проблема с настраиваемым классом, который был определен в пространстве имен. Я попытался использовать класс без пространства имен, что вызвало ошибку компилятора «идентификатор« MyClass »не определен». Добавление

using namespace <MyNamespace>

или используя класс вроде

MyNamespace::MyClass myClass;

решил проблему.

person Dimitar Dimitrov    schedule 30.01.2017

Эти сообщения об ошибках

1.For the Visual Studio compiler: error C2065: 'printf' : undeclared identifier
2.For the GCC compiler: `printf' undeclared (first use in this function)

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

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

В этом конкретном случае компилятор не видит объявление имени printf. Как мы знаем (но не компилятору), это имя стандартной функции C, объявленной в заголовке <stdio.h> в C или в заголовке <cstdio> в C ++ и помещенной в стандартные (std::) и глобальные (::) (не обязательно) пространства имен.

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

Например C:

#include <stdio.h>

int main( void )
{
   printf( "Hello World\n" );
}

C ++:

#include <cstdio>

int main()
{
   std::printf( "Hello World\n" );
   // or printf( "Hello World\n" );
   // or ::printf( "Hello World\n" );
}

Иногда причина такой ошибки - простая опечатка. Например, предположим, что вы определили функцию PrintHello

void PrintHello()
{
    std::printf( "Hello World\n" );
}

но в основном вы допустили опечатку и вместо PrintHello набрали printHello со строчной буквой «p».

#include <cstdio>

void PrintHello()
{
    std::printf( "Hello World\n" );
}

int main()
{
   printHello();
}

В этом случае компилятор выдаст такую ​​ошибку, потому что он не видит объявление имени printHello. PrintHello и printHello - два разных имени, одно из которых было объявлено, а другое не было объявлено, но использовалось в теле основного

person Vlad from Moscow    schedule 05.03.2014
comment
В C ++ версии без std:: не гарантируются. - person M.M; 17.03.2016

Это случилось со мной, когда средство автоматического форматирования в проекте Visual Studio отсортировало мои включения, после чего предварительно скомпилированный заголовок больше не был первым включением.

Другими словами. Если у вас есть что-либо из этого:

#include "pch.h"

or

#include <stdio.h>

or

#include <iostream>
#include "stdafx.h"

Поместите его в начало вашего файла.

Если ваш форматировщик clang автоматически сортирует файлы, попробуйте поставить ввод после предварительно скомпилированного заголовка. Если он находится в IBS_Preserve, он будет отсортировать каждый блок #include отдельно.

#include "pch.h"  // must be first

#include "bar.h"  // next block
#include "baz.h"
#include "foo.h"

Дополнительная информация на Ошибка компилятора C2065

person Goosebumps    schedule 09.01.2020

Идентификатор C ++ - это имя, используемое для идентификации переменной, функции, класса, модуля или любого другого определяемого пользователем элемента. В C ++ все имена должны быть объявлены до их использования. Если вы попытаетесь использовать имя такого, которое не было объявлено, вы получите ошибку компиляции необъявленного идентификатора.

Согласно документации, объявление printf() находится в cstdio, т.е. вы должны включить перед использованием функции.

person Amit G.    schedule 23.07.2018

Другая возможная ситуация: доступ к родительскому (шаблонному классу) члену в шаблонном классе.

Метод исправления: использование члена родительского класса по его полному имени (путем добавления префикса this-> или parentClassName:: к имени члена).

см. шаблоны: родительский класс переменные-члены не отображаются в унаследованном классе

person phil    schedule 24.10.2018

еще один случай, когда эта проблема может возникнуть,

if(a==b)
double c;
getValue(c);

здесь значение объявляется в условии, а затем используется вне его.

person Sanket    schedule 18.12.2019

Это похоже на использование функции без ее объявления. Заголовочный файл будет содержать функцию printf (). Включите файл заголовка в свою программу, это решение для этого. Некоторые пользовательские функции могут также вызывать ошибку, если не были объявлены перед их использованием. Если он используется глобально, проблем нет.

person Q_SaD    schedule 05.03.2014

В большинстве случаев, если вы уверены, что импортировали нужную библиотеку, Visual Studio поможет вам с помощью IntelliSense.

Вот что у меня сработало:

Убедитесь, что #include "stdafx.h" объявлен первым, то есть вверху всех ваших включений.

person Declan Nnadozie    schedule 23.07.2018

Каждая необъявленная переменная в c возникает из-за того, что компилятор не может найти ее в проекте. Можно включить внешний (заголовочный) файл библиотеки, в которой определена переменная. Следовательно, в вашем вопросе вам требуется <stdio.h>, это стандартный файл ввода-вывода, который описывает функциональность printf ().

Согласно документации, объявление fprintf () находится внутри, т.е. вы должны включите его перед использованием функции.

person Ishmeet    schedule 05.03.2014
comment
По ошибке отредактировал ваш ответ. Я намеревался отредактировать свой. - person Amit G.; 23.07.2018

Проверьте, импортируете ли вы одни и те же пакеты в свой .m и в свой .h Пример: у меня была эта проблема с методом инициализации, и она была вызвана отсутствием символа «#import» в файле .m

person manuesev    schedule 17.10.2016