Что произойдет, если мы вызовем функцию area() следующим образом:
int s1 = area(7; // ошибка: пропущена скобка )
int s2 = area(7) // ошибка: пропущена точка с запятой ;
Int s3 = area(7); // ошибка: Int — это не тип
int s4 = area('7); // ошибка: пропущена кавычка '
Каждая из этих строк содержит синтаксическую ошибку; иначе говоря, они не соответствуют грамматике языка С++, поэтому компилятор их отклоняет. К сожалению, синтаксические ошибки не всегда можно описать так, чтобы программист легко понял, в чем дело. Это объясняется тем, что компилятор должен проанализировать немного более крупный фрагмент текста, чтобы понять, действительно ли он обнаружил ошибку. В результате даже самые простые синтаксические ошибки (в которые даже невозможно поверить) часто описываются довольно запутанно, и при этом компилятор ссылается на строку, которая расположена в программе немного дальше, чем сама ошибка. Итак, если вы не видите ничего неправильного в строке, на которую ссылается компилятор, проверьте предшествующие строки программы.
Обратите внимание на то, что компилятор не знает, что именно вы пытаетесь сделать, поэтому формулирует сообщения об ошибках с учетом того, что вы на самом деле сделали, а не того, что намеревались сделать. Например, обнаружив ошибочное объявление переменной s3
, компилятор вряд ли напишет что-то вроде следующей фразы:
“Вы неправильно написали слово int
; не следует употреблять прописную букву i
.”
Скорее, он выразится так:
“Синтаксическая ошибка: пропущена ';'
перед идентификатором 's3'
”
“У переменной 's3'
пропущен идентификатор класса или типа”
“Неправильный идентификатор класса или типа 'Int'
”
Такие сообщения выглядят туманными, пока вы не научитесь их понимать и использовать. Разные компиляторы могут выдавать разные сообщения, анализируя один и тот же код. К счастью, вы достаточно скоро научитесь понимать эти сообщения без каких-либо проблем. В общем, все эти зашифрованные сообщения можно перевести так:
“Перед переменной s3
сделана синтаксическая ошибка, и надо что-то сделать либо с типом Int
, либо с переменной s3
.”
Поняв это, уже нетрудно решить проблему.
ПОПРОБУЙТЕ
Попробуйте скомпилировать эти примеры и проанализируйте ответы компиляторов.
5.3.2. Ошибки, связанные с типами
После того как вы устраните синтаксические ошибки, компилятор начнет выдавать сообщения об ошибках, связанных с типами; иначе говоря, он сообщит о несоответствиях между объявленными типами (или о типах, которые вы забыли объявить) ваших переменных, функций и так далее и типами значений и выражений, которые вы им присваиваете, передаете в качестве аргументов и т.д.
int x0 = arena(7); // ошибка: необъявленная функция
int x1 = area(7); // ошибка: неправильное количество аргументов
int x2 = area("seven",2); // ошибка: первый аргумент
// имеет неправильный тип
Рассмотрим эти ошибки.
1. При вызове функции arena(7)
мы сделали опечатку: вместо area
набрали arena, поэтому компилятор думает, что мы хотим вызвать функцию с именем arena
. (А что еще он может “подумать”? Только то, что мы сказали.) Если в программе нет функции с именем arena()
, то вы получите сообщение об ошибке, связанной с необъявленной функцией. Если же в программе есть функция с именем arena
, принимающая число 7
в качестве аргумента, то вы столкнетесь с гораздо худшей проблемой: программа будет скомпилирована как ни в чем ни бывало, но работать будет неправильно (такие ошибки называют логическими; см. раздел 5.7).
2. Анализируя выражение area(7)
, компилятор обнаруживает неправильное количество аргументов. В языке C++ вызов каждой функции должен содержать ожидаемое количество аргументов, указанных с правильными типами и в правильном порядке. Если система типов используется корректно, она становится мощным инструментом, позволяющим избежать ошибок на этапе выполнения программы (см. раздел 14.1).
3. Записывая выражение area("seven",2)
, вы могли рассчитывать, что компилятор увидит строку "seven
" и поймет, что вы имели в виду целое число 7
. Напрасно. Если функция ожидает целое число, то ей нельзя передавать строку. Язык C++ поддерживает некоторые неявные преобразования типов (см. раздел 3.9), но не позволяет конвертировать тип string
в тип int
. Компилятор даже не станет угадывать, что вы имели в виду. А что вы могли бы ожидать от вызовов area("Hovel lane",2)
, area("7,2")
и area("sieben","zwei")
?
Мы перечислили лишь несколько примеров. Существует намного больше ошибок, которые компилятор может найти в вашей программе.
ПОПРОБУЙТЕ