Назад | Начало урока | Вперед
Содержание

Глава 23

Десять синтаксических ошибок

В этой главе...

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

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

Вверх

Подключаемый файл не может быть найден

Сообщение:

fatal error C1083: Cannot open include file: 'foo.h' : No such file or directory

Эта ошибка является одной из самых распространенных. Обычно ей предшествует целый набор сообщений о том, что тот или иной элемент не может быть определен.
Проверьте, расположен ли заголовочный файл, который должен быть подключен к вашей программе, в одной папке с исходными файлами. Если его там нет, то он обязательно должен быть размещен в одной из папок, содержащих подключаемые файлы. Чтобы проверить, какие именно папки содержат подключаемые файлы, выберите команду ToolS^Options (Сервис^-Параметры) и в открывшемся диалоговом окне в разделе Projects выберите категорию VC++ Directories. В списке Show Directories For (Показать папки для...) выберите пункт Include Files (Подключаемые файлы).
Кроме того, эта ошибки может быть вызвана тем. что, набирая название заголовочного
файла, вы заключили его не в кавычки (" " ). а в угловые скобки (< >). Используйте кавычки
в тех случаях, если заголовочный файл размещен в той же папке, что и исходные файлы, поскольку те файлы, названия которых набраны в УГЛОВЫХ скобках, компилятор ищет только в папках, которые определены как содержащие подключаемые файлы.

Вверх

Пропущена точка с запятой

Сообщении:

error C2628: 'bar' followed by 'int' is illegal (did you forget a ';' ? )
error C2144: syntax error : int' should be preceded by ';'
error C2143: syntax error : missing ';' before '}'

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

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

Очень часто забывают набирать точку с запятой после фигурной скобки, которой заканчивается определение класса. (В этом случае сообщение об ошибке будет выглядеть примерно как unexpected ' c l a s s ' ' f oo '.) Если вам нужна дополнительная информация о правилах использования точек с запятой, обратитесь к главе 12.

Вверх

Не подключен заголовочный файл
Сообщения:
error C2065: 'а1 : undeclared identifier
error C2065: ' sin 1 : undeclared identifier
error C2440: '=' : cannot convert from ' ' unknown - type ' ' to ' 'unknown - type' '

Еще одна классическая ошибка— неподключенный заголовочный файл. Результатом будет
появление самых различных сообщений, среди которых обычно есть сообщения о том,
что класс, тип или функция не определены или что возвращаются данные не того типа.
Подобные проблемы очень часто возникают тогда, когда вы используете библиотечные
функции, но забываете подключить соответствующие им заголовочные файлы. Например, если для
отображения информации на экране вы используете функцию сout, не забудьте подключить
файл iostream.h; если для вычисления квадратного корня вы используете функцию
sort, не забудьте подключить файл maih.h.

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

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

Вверх

Не обновлено объявление класса
Сообщения:

error C2039: 'с' : is not a member of 'test5'
error LFK2001: unresolved external symbol "?bar@foo@ AEXXZ
(public: void thisoall foo::bar(void))"

Очень часто программисты (особенно те, которые раньше программировали на языке С, а потом
перешли на C++) забывают обновлять объявления классов. В результате появляются сообщения о
том, что один элемент не является членом другого — baz is nor a member of
foo (эти сообщения генерирует компилятор), или об использовании недопустимой внешней ссылки (unresolved external symbol —эти сообщения генерирует компоновщик).

Сообщение о недопустимой внешней ссылке на самом деле подразумевает возникновение
проблем при использовании скорректированных имен. Скорректированные имена рассматривались в паве 7: компилятор создает для каждого элемента скорректированное имя с тем,
чтобы все они были уникальны. Например, если вы используете имя foo::bar(), компилятор преобразует его в ?bar@foo@ AEXXZ.

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

Вверх

Использование названия класса вместо названия объекта

Сообщения:

warning C4832: token '.' is illegal after UDT 'errcr7'
error C2215: 'errorV : illegal use of this type as an expression
error C2143: syntax error : missing ';' before '.'

Еще одна ошибка, которую обычно совершают программисты, которые ранее программировали на языке С, состоит в том, что при доступе к функции-члену или члену данных класса используется не название объекта, а название самого класса. В таких случаях обычно появляется сообщение о том, что использован неверный типа данных. Также может появиться сообщение о том, что проблемы вызваны неправильным использованием точки (.) или оператора ->.

Помните, что название класса и название объекта этого класса— совершенно разные
имена. Предположим, например, что у вас есть такой код:

CDialog foo;

В данном случае foo является объектом класса CDialog.
Если вам нужно вызвать функцию-член DoModal, наберите

foo.DoModal();

Но не набирайте

CDiaiog.DoModal();

Вверх

После объявления класса не поставлена точка с запятой
Сообщения: <з> error C2146: syntax error : missing ';' before identifier 'foo'
fatal error C1004: unexpected end of file found <з> Если вы забудете поставить точку с запятой после объявления класса, это приведет к появлению множества сообщений об ошибках. Такая ошибка случается довольно часто, а потому ее можно назвать одной из самых распространенных. Более подробную информацию об этом вы можете найти в разделе "Пропущена точка с запятой".

Вверх

В определении класса пропущено слово public:
Сообщения:

error C2248: 'error8a :: a' : cannot access private member
declared in class 'error8a'

Еще одна распространенная ошибка— не набранное слово public: при определении
класса. При этом может появиться сообщение наподобие такого:

error С2248: 'bar' : cannot access private member declared in class 'foo' .

По умолчанию все функции-члены и члены данных класса являются закрытыми. Именно
поэтому, если вы не сделаете их открытыми, набрав перед их определением ключевое слово
public: , вы получите сообщение, показанное выше.
Например, если вы наберете такой код, доступ к переменной bar будут иметь только
функции-члены этого же класса:

class foo
{

int bar;
};

Поэтому такое обращение к переменной bar неправомочно:

foo salad;
salad.bar = 1;

Если же вы наберете код, приведенный ниже, переменную bar можно будет использовать
везде, где применяются объекты класса foo, и к обращению salad.bar у компилятора не
будет никаких претензий.

class foo
{

public:
int bar;
}

Вверх

Неправильно набранные имена переменных
Сообщение:

error C2065: 'b' : undeclared identifier

Запутаться в именах переменных очень легко. При этом вы можете получить сообщение
наподобие 'SongsNum' : undeclared identifier . Если вы пишете большую про-
грамму, то вполне можно забыть, как именно переменная была названа: SongsNum или
NumSongs. Если ошибиться хотя бы на один символ, это тут же приведет к возникновению
синтаксической ошибки. В таком случае вернитесь к объявлению переменной и уточните ее
имя. Те же проблемы возникают и при неправильном наборе имени класса или функции.

Вверх

Использование точки вместо стрелки и наоборот
Сообщения: <з> error C2818: type 'еггог 'f' does not have an overloaded member
'operator ->'
error C2227: left of '->f must point to class/struct/union
error C2143: syntax error : missing ';' before '.'

Вы можете по ошибке использовать оператор -> вместо точки, если забудете, что имеете
дело со ссылкой на класс, а не с указателем. Это происходит, если кто-то постоянно работает
с указателями и в какой-то момент начинает к каждому элементу относиться как к указателю.
Результатом будет появление приблизительно такого сообщения об ошибке:

error C2231:'.foo::oar':left operand point s to 'class', use ' - > ' .

Например, такой код содержит в себе ошибку:

CDialog foo;
foo~>DoMorial();

Проблема в том. что foo является названием объекта класса CDiaiog, а не указателем на
такой объект. Правильно будет использовать такой код:

foo.DoModal () ;

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

error C2227: left of '-> bar' must point to class/struct/union.

Например, следующий код неверен:

CDialcg *foo;
foo.DoModal();

В данном случае foo является ссылкой на объект класса CDialog, а не самим объектом.
Чтобы вызвать функцию DoModal, нужно набрать такой код:

foo->DoModal();

Вверх

Пропущена закрывающая фигурная скобка
Сообщение:

fatal error C!1004: unexpected end of file found

Пропущенная закрывающая фигурная скобка— это более простительная ошибка, чем не
поставленная точка с запятой. Обычно это случается при создании функций, содержащих в себе много вложенных операторов if или других блоков команд. Если количество открывающих скобок не соответствует количеству закрывающих, компилятор выдает сообщение о неисправимой ошибке (fatal error) ; в действительности это означает, что в поисках закрывающей фигурной скобки уже достигнут конец файла, а скобка так и не найдена.

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


Назад | Начало урока | Вверх | Вперед
Содержание