Skip to the content of the web site.

Lesson 2b: Syntax errors

Previous lesson Next lesson


At this point, you may have made an error in entering your code so that the compiler does not actually run, but rather it indicates an error during compilation.

The compiler understands a limited expression of code as defined by the C++ programming language. For example, if you forget a semi-colon at the end of a statement, the compiler no longer knows that that was the end of a statement— even if it is at the end of a line:

	std::cout << "Hello world!" < std::endl
	std::cout << "Good night!" < std::endl;

It will treat this as a single statement:

	std::cout << "Hello world!" < std::endl std::cout << "Good night!" < std::endl;

and the compiler will not know what to do when you have a std::endl object juxtaposed to a std::cout statement. In spoken English, either a pause usually indicates the end of a sentence, but the listener can also infer when a sentence ends. The compiler will not guess when you meant to end a sentence.

For example, suppose you say "Let's go to dinner. After lunch, give me a call." If the speaker does not leave a pause between "dinner" and "after", the listener may initially believe that the preposition "after" is meant to start an prepositional phrase meant to modify the verb "go"; however, the listener soon realizes that the statement "Let's go to dinner after lunch" makes no real sense, so the listener is able to switch context and realize that the sentence ended after "dinner" and "After lunch" is the start of a new sentence.

Similarly, every string opens with a ", and closes with one, but if you forget the first, the compiler will not try to interpret the next few characters as a string literal, but as something else. For example, in the following line, all the characters in red are considered the literal string, and then the compiler gets confused when it sees a string juxtaposed with the characters Good:

	std::cout << "Hello world! << std::endl;
	std::cout << "Good night! << std::endl;

Humans can forgive such errors; for example, it is an idiotic manner of speech for people to say "quote unquote" preceding a quote. Far too often, someone will actually say "Einstein said quote unquote Imagination is more important than knowledge, and I believe that to be true." The speaker should have said "Einstein said, quote, Imagination is more important than knowledge, unquote, and I believe that to be true." A human can likely determine where the quote ends; however, the compiler will not.

As another example, suppose you entered:

	std::cout << "Hello world!" < std::endl;

The << operator means one thing in C++, while the < operator means something else. Suppose an English speaker were to say "Please calculate 3 eks 4". The listener can guess that "x" looks like a multiplication symbol, and therefore the speaker is attempting to say "Please calculate 3 multiplied by 4." The compiler, however, will not attempt to second guess you. In the above example, the less-than operator does not make any sense between a string and a std::endl.

Similarly, if you incorrectly identify the end-of-line object:

	std::cout << "Hello world!" << std::end;

the compiler cannot and will not guess that you really meant std::endl. For if a listener heard "What affect did that have on the discussion?", the listener could guess that the speaker made a mistake and meant "what effect did that have on the discussion?" The compiler, however, will not try to guess what you meant.

Consequently, unlike spoken English where if the speaker make a mistake, the listener can correct for your mistakes, the compiler will not try to correct your mistake. Instead, it will try to tell you what it doesn't understand.

Like English grammar, the C++ programming language also has a grammar. When you make an error in English where you are using incorrect grammar, that is said to be an error in your syntax. The listener may either attempt to reinterpret your sentence in such a way that it makes sense in the current context, or ask for clarification. The compiler, however, will simply tell you that you have a syntax error.

Definition: grammar
A logical description of what sequences of characters constitute a valid program in a given programming language; consequently, all other sequences of characters do not define a valid program within the language.

Definition: syntax error
An unexpected sequence of characters that is not comprehensible within the grammar of a programming language.

The compiler, however, does try to give you a hint as to what is wrong. Suppose we take the Hello world! program and introduce syntactical errors:

  1   #include <iostream>
  2
  3   int main() {
  4   	std::cout << "Hello world!" << std::endl;
  5   	std::cout << "Good night!" << std::endl;
  6 
  7   	return 0;
  8   }

Let us make the first syntax error: forgetting the semicolon after the first statement with std::cout. If you try to run this, under the compilation tab, you see the message:

 In function 'int main()':
5:5: error: expected ';' before 'std'

First, the error message says where it things the error is: in the function int main(). Next, it gives two numbers: 5:5: The first number is the line number, and the second number is the column. At this point, the compiler is indicating that there probably should have been a semicolon there:

  4   	std::cout << "Hello world!" << std::endl
  5   	;std::cout << "Good night!" << std::endl;

Now, we could put the semicolon there, but it looks "nicer" if the semicolon appeared at the end of the previous line.

Second, if you forget to close the first string with a quote, you get the error message:

4:18: warning: missing terminating " character
4:5: error: missing terminating " character

Again, it indicates the line where the problem occurs. First it issues a warning (a string cannot span multiple lines). Then it gets confused and issues an error.

Next, let us make the error where we replace one of the << operators with the < operator. The error message is now bewildering:

 In function 'int main()':
4:33: error: no match for 'operator<' (operand types are 'std::basic_ostream<char>' and '<unresolved overloaded function type>')
4:33: note: candidates are:
In file included from /usr/include/c++/4.9/string:52:0,
                 from /usr/include/c++/4.9/bits/locale_classes.h:40,
                 from /usr/include/c++/4.9/bits/ios_base.h:41,
                 from /usr/include/c++/4.9/ios:42,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from 1:
/usr/include/c++/4.9/bits/basic_string.h:2612:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
     operator<(const _CharT* __lhs,
     ^

/usr/include/c++/4.9/bits/basic_string.h:2612:5: note: template argument deduction/substitution failed:
4:40: note: mismatched types 'const _CharT*' and 'std::basic_ostream<char>'
In file included from /usr/include/c++/4.9/string:52:0,
                 from /usr/include/c++/4.9/bits/locale_classes.h:40,
                 from /usr/include/c++/4.9/bits/ios_base.h:41,
                 from /usr/include/c++/4.9/ios:42,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from 1:
/usr/include/c++/4.9/bits/basic_string.h:2600:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
     ^
/usr/include/c++/4.9/bits/basic_string.h:2600:5: note: template argument deduction/substitution failed:
4:40: note: 'std::basic_ostream<char>' is not derived from 'const std::basic_string<_CharT, _Traits, _Alloc>'
In file included from /usr/include/c++/4.9/string:52:0,
                 from /usr/include/c++/4.9/bits/locale_classes.h:40,
                 from /usr/include/c++/4.9/bits/ios_base.h:41,
                 from /usr/include/c++/4.9/ios:42,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from 1:
/usr/include/c++/4.9/bits/basic_string.h:2588:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
     operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
     ^
/usr/include/c++/4.9/bits/basic_string.h:2588:5: note: template argument deduction/substitution failed:
4:40: note: 'std::basic_ostream<char>' is not derived from 'const std::basic_string<_CharT, _Traits, _Alloc>'
In file included from /usr/include/c++/4.9/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/4.9/bits/char_traits.h:39,
                 from /usr/include/c++/4.9/ios:40,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from 1:
 + almost 100 more lines of error messages...

From the verbosity of this error message, you may think that you suddenly committed a cardinal sin; however, what the compiler is doing is trying to tell you why it is confused and when you have a better understanding of C++, you know it is trying to help you by giving suggestions. The most important line for you, however, is the first:

 In function 'int main()':
4:33: error: no match for 'operator<' ...
This says that on line 4 at column 33, the compiler does not know what to do with the < operator.

Unfortunate, if you were to incorrectly spell std::endl and replace it with std::end, the error message is less clear, but reading the first two lines:

 In function 'int main()':
4:33: error: no match for 'operator<<' (operand types are 'std::basic_ostream<char>' and '<unresolved overloaded function type>')
 + almost 100 more lines of error messages...

What this error message says is that it does not understand how it is supposed to have a << operator work with something it doesn't comprehend. It actually describes the std::end as an unresolved overloaded function type. While the error message is not entirely useful, it does point you to approximately where the error is.

Finally, a very common error is to forget the closing brace. If you forget the closing brace }, you get the error message:

 In function 'int main()':
7:13: error: expected '}' at end of input

In this case, it is telling you exactly what is missing, and you can add it.

If it tells you what is wrong, why not fix it?

In at least two examples above (with the missing semicolon and the missing closing brace) the error message told you exactly what was wrong and how to fix it. You may ask, why does the compiler simply not make the corrections and then carry on? The problem is, what it thinks is the right correction to make may not be what you actually meant!

Important suggestion:
As you go forward and learn new aspects of the C++ programming language, it may not be that bad an idea to occasionally make deliberate mistakes so that you can see what the error messages are.

Review

In your own words, describe each of these concepts:

Questions and practice:

1. What error do you get if you misspell return?

2. What happens if you misspell the function name main, say with min?

3. If you misspelled include, you get a cascade of subsequent errors. If there are multiple errors, always try to fix the first error first; this may eliminate subsequent errors.

4. If you write int main(] { instead of using a closing parenthesis, what are the errors? How is the error worded?


Previous lesson Next lesson