Как читать ошибки компилятора C++: expected ';', was not declared in this scope и другие

Как устроено сообщение об ошибке компилятора C++ и что означают самые частые из них: expected ';' before, was not declared in this scope, expected '}' at end of input, cannot convert и другие. Настоящие сообщения GCC с разбором и исправлением.

Содержание

Программа не скомпилировалась, и экран заполнился текстом с непонятными словами. Первое желание — закрыть его и начать менять код наугад. Между тем в сообщении компилятора почти всегда написано, где ошибка и в чём она состоит. Нужно только знать, куда смотреть.

Все сообщения в статье получены настоящим компилятором GCC 14. В Clang и Visual Studio формулировки другие, но устроены они так же; соответствие — в таблице в конце.

Из чего состоит сообщение

Возьмём программу с пропущенной точкой с запятой.

main.cpp
C++
#include <iostream>

int main() {
    int a = 5;
    std::cout << a << '\n'
    return 0;
}
TXT
main.cpp: In function 'int main()':
main.cpp:5:27: error: expected ';' before 'return'
    5 |     std::cout << a << '\n'
      |                           ^
      |                           ;
    6 |     return 0;
      |     ~~~~~~

Разберём по частям.

  • main.cpp: In function 'int main()' — в каком файле и в какой функции.
  • main.cpp:5:27 — файл, строка и позиция в строке. Здесь строка 5, символ 27.
  • error — вид сообщения. Бывает ещё warning (предупреждение: программа соберётся, но код подозрителен) и note (пояснение к предыдущему сообщению).
  • expected ';' before 'return' — суть: ожидалась точка с запятой перед return.
  • Ниже — сама строка кода, значок ^ под местом ошибки и подсказка, что вставить.

Три правила

Читайте первую ошибку. Одна пропущенная скобка может породить десяток сообщений: компилятор сбивается и перестаёт понимать код дальше. Исправьте первую ошибку и скомпилируйте заново — остальные часто исчезают сами.

Смотрите на строку выше. Компилятор замечает проблему там, где код перестал быть осмысленным, а это часто на строку ниже настоящей причины. В примере пропущена ; в строке 5, а «мешает» компилятору return из строки 6.

Читайте пояснения note. В них компилятор показывает связанное место: где открыта незакрытая скобка, где переменная объявлена в первый раз, какую функцию он нашёл.

expected ';' before …

TXT
main.cpp:5:27: error: expected ';' before 'return'

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

TXT
main.cpp:5:5: error: expected ',' or ';' before 'std'

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

Отдельный случай — точка с запятой после определения структуры или класса. Её забывают чаще всего:

C++
struct Point {
    int x;
    int y;
}          // здесь нужна ;
TXT
main.cpp:4:2: error: expected ';' after struct definition

'x' was not declared in this scope

TXT
main.cpp:5:18: error: 'cuont' was not declared in this scope; did you mean 'count'?

Компилятор встретил имя, которого не знает. Причин четыре.

Опечатка. Компилятор сам предлагает похожее имя: did you mean 'count'?

Переменная объявлена ниже, чем используется. Имя существует только после своего объявления:

C++
std::cout << b << '\n';   // ошибка: b ещё нет
int b = 7;

Переменная объявлена в другом блоке. Имя, объявленное внутри фигурных скобок, снаружи не видно:

C++
if (n > 0) {
    int square = n * n;
}
std::cout << square;      // ошибка: square осталась внутри if

Забыт std:: или заголовок. Если написать cout без std::, компилятор подскажет:

TXT
main.cpp:4:5: error: 'cout' was not declared in this scope; did you mean 'std::cout'?

А если не подключён <iostream>, подсказки не будет вовсе — только 'cout' was not declared in this scope. Проверьте строки #include в начале файла.

expected '}' at end of input

TXT
main.cpp:9:2: error: expected '}' at end of input
main.cpp:3:12: note: to match this '{'

Файл закончился, а фигурная скобка осталась незакрытой. Строка в самом сообщении — последняя в файле, и искать там нечего. Полезна вторая строка, note: она показывает открывающую скобку, которой не хватило пары. В примере это скобка функции main, а потерялась на самом деле скобка, закрывающая if:

C++
int main() {
    int n = 3;
    if (n > 0) {
        std::cout << "positive\n";
                                  // здесь пропущена }
    return 0;
}

Чтобы такие ошибки не появлялись, ставьте закрывающую скобку сразу после открывающей и держите ровные отступы: потерянная скобка заметна по «съехавшему» коду.

expected primary-expression before …

TXT
main.cpp:4:22: error: expected primary-expression before ')' token

Компилятор ждал значение — число, переменную, вызов функции — а встретил что-то другое. Обычно это пропущенный операнд или лишний знак:

C++
int total = (3 + ) * 2;   // после + ничего нет

Это же сообщение часто появляется вторым, как следствие другой ошибки. Например, из-за незакрытой круглой скобки в условии:

C++
if (n > 0 {
TXT
main.cpp:5:14: error: expected ';' before '{' token
main.cpp:8:5: error: expected primary-expression before 'return'
main.cpp:7:6: error: expected ')' before 'return'

Три ошибки, а причина одна — пропущенная ). Поэтому правило «читайте первую ошибку и смотрите на строку рядом» здесь особенно важно.

cannot convert … to …

TXT
main.cpp:5:18: error: cannot convert 'std::string' {aka 'std::__cxx11::basic_string<char>'} to 'int' in initialization

Значение одного типа нельзя положить в переменную другого. В примере строку пытаются присвоить целому числу:

C++
std::string name = "Анна";
int length = name;          // нужно name.size()

Длинное {aka …} — это «также известен как»: настоящее внутреннее имя типа. Читать его не обязательно, достаточно пары «из чего» и «во что».

too many arguments to function

TXT
main.cpp:6:24: error: too many arguments to function 'int square(int)'
main.cpp:1:5: note: declared here

Функции передали больше аргументов, чем она принимает. note показывает объявление функции — сверьте список параметров. Зеркальная ошибка называется too few arguments to function.

redeclaration of …

TXT
main.cpp:5:9: error: redeclaration of 'int a'
main.cpp:4:9: note: 'int a' previously declared here

Переменная объявлена дважды в одном блоке. Чаще всего это лишнее слово int там, где нужно было просто присвоить новое значение: a = 2; вместо int a = 2;.

void value not ignored as it ought to be

TXT
main.cpp:8:23: error: void value not ignored as it ought to be

Вы пытаетесь использовать результат функции, которая ничего не возвращает:

C++
void print(int value) { std::cout << value << '\n'; }

int result = print(5);     // print ничего не возвращает

Либо функция должна возвращать значение (тогда замените void на нужный тип и добавьте return), либо результат не нужно никуда сохранять.

Предупреждения — тоже ошибки, только вежливые

Программа с предупреждениями соберётся, но работать может неправильно. Включите их флагами -Wall -Wextra:

Bash
g++ -std=c++26 -Wall -Wextra main.cpp -o main

Три предупреждения, на которые стоит реагировать всегда.

ПредупреждениеЧто случилось
suggest parentheses around assignment used as truth valueВ условии стоит = вместо ==: if (a = 7) присваивает, а не сравнивает
control reaches end of non-void functionФункция должна вернуть значение, но в какой-то ветке нет return
comparison of integer expressions of different signednessСравниваются знаковое и беззнаковое числа, например int i и numbers.size()

Второе предупреждение особенно коварно: функция без return скомпилируется, а в момент вызова поведение программы не определено. Что это значит на практике — в статье «Мусор в переменных и неопределённое поведение в C++».

То же самое в Clang и Visual Studio

GCCClangVisual Studio
expected ';' before 'return'expected ';' after expressionC2143: syntax error: missing ';' before 'return'
'x' was not declared in this scopeuse of undeclared identifier 'x'C2065: 'x': undeclared identifier
expected '}' at end of inputexpected '}'C1075: '{': no matching token found

Порядок действий

  1. Найдите самую первую строку со словом error.
  2. Откройте файл на указанной строке. Посмотрите на неё и на строку выше.
  3. Прочитайте суть сообщения и строки note под ним.
  4. Исправьте одну ошибку и скомпилируйте заново.
  5. Повторяйте, пока ошибок не останется, затем разберитесь с предупреждениями.

Ошибки компиляции — самые простые из всех: компилятор сам показывает место. Сложнее, когда программа собралась, но не связалась или упала при запуске. Об этом — статьи «Ошибка undefined reference в C++» и «Segmentation fault в C++».

Если компилятор ещё не установлен, начните с урока учебника «Введение в C++: история, компиляция и первая программа».

Источники

  1. Options to Request or Suppress Warnings — GCC Manual [Электронный ресурс]. — URL: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html (дата обращения: 10.10.2026).
  2. Scope — cppreference.com [Электронный ресурс]. — URL: https://en.cppreference.com/w/cpp/language/scope (дата обращения: 10.10.2026).
  3. Compiler Error C2065 — Microsoft Learn [Электронный ресурс]. — URL: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2065 (дата обращения: 10.10.2026).
C++Компилятор