EXPLORATION 6

image

Error Messages

By now you’ve seen plenty of error messages from your C++ compiler. No doubt, some are helpful and others are cryptic—a few are both. This Exploration presents a number of common errors and gives you a chance to see what kinds of messages your compiler issues for these mistakes. The more familiar you are with these messages, the easier it will be for you to interpret them in the future.

Read through Listing 6-1 and keep an eye out for mistakes.

Listing 6-1.  Deliberate Errors

 1 #include <iosteam>
 2 // Look for errors
 3 int main()
 4 [
 5   std::cout < "This program prints a table of squares. ";
 6          "Enter the starting value for the table: ";
 7   int start{0};
 8   std::cin >> start;
 9   std::cout << "Enter the ending value for the table: ";
10   int end(start);
11   std::cin << endl
12   std::cout << "#   #^2 ";
13   int x{start};
14   end = end + 1; // exit loop when x reaches end
15   while (x != end)
16   {
17     std:cout << x << "   " << x*x << " ";
18     x = x + 1;
19   }
20 }

What errors do you expect the compiler to detect?

_____________________________________________________________

_____________________________________________________________

_____________________________________________________________

_____________________________________________________________

_____________________________________________________________

_____________________________________________________________

Download the source code and compile Listing 6-1.

What messages does your compiler actually issue?

_____________________________________________________________

_____________________________________________________________

_____________________________________________________________

_____________________________________________________________

_____________________________________________________________

_____________________________________________________________

_____________________________________________________________

Create three groups: messages that you correctly predicted, messages that you expected but the compiler did not issue, and messages that the compiler issued but you did not expect. How many messages are in each group? ________________

If you use command-line tools, expect to see a slew of errors running across your screen. If you use an IDE, it will help corral the error messages and associate each message with the relevant point in the source code that the compiler thinks is the cause of the error. The compiler isn’t always right, but its hint is often a good starting point.

Compilers usually group problems into one of two categories: errors and warnings. An error prevents the compiler from producing an output file (an object file or program). A warning tells you that something is wrong but doesn’t stop the compiler from producing its output. Modern compilers are pretty good at detecting problematic, but valid, code and issuing warnings, so get in the habit of heeding the warnings. In fact, I recommend dialing up the sensitivity to warnings. Check your compiler’s documentation and look for options that have the compiler detect as many warnings as possible. For g++ and clang++, the switch is -Wall. Visual Studio uses /Wall. On the other hand, sometimes the compiler gets it wrong, and certain warnings are not helpful. You can usually disable individual warnings, such as -Wno-unused-local-typedefs (my favorite for g++) or /wd4514 (for Visual Studio).

The program actually contains seven errors, but don’t fret if you missed them. Let’s take them one at a time.

Misspelling

Line 1 misspells<iostream> as <iosteam>. Your compiler should give you a simple message, informing you that it could not find <iosteam>. The compiler probably cannot tell that you meant to type <iostream>, so it does not give you a suggestion. You have to know the proper spelling of the header name.

Most compilers give up completely at this point. If that happens to you, fix this one error then run the compiler again, to see some more messages.

If your compiler tries to continue, it does so without the declarations from the misspelled header. In this case, <iostream> declares std::cin and std::cout, so the compiler also issues messages about those names being unknown, as well as other error messages about the input and output operators.

Bogus Character

The most interesting error is the use of a square-bracket character ([) instead of a brace character ({) in line 4. Some compilers may be able to guess what you meant, which can limit the resulting error messages. Others cannot and give a message that may be rather cryptic. For example, g++ issues many errors, none of which directly points you to the error. Instead, it issues the following messages:

list0601.cpp:5:58: error: array bound is not an integer constant before ';' token

   std::cout < "This program prints a table of squares. ";
                                                          ^
list0601.cpp:5:58: error: expected ']' before ';' token
list0601.cpp:6:10: error: expected unqualified-id before string constant
          "Enter the starting value for the table: ";
          ^
list0601.cpp:8:3: error: 'cin' in namespace 'std' does not name a type
   std::cin >> start;
   ^
list0601.cpp:9:3: error: 'cout' in namespace 'std' does not name a type
   std::cout << "Enter the ending value for the table: ";
   ^
list0601.cpp:11:3: error: 'cin' in namespace 'std' does not name a type
   std::cin << endl
   ^
list0601.cpp:14:3: error: 'end' does not name a type
   end = end + 1; // exit loop when x reaches end
   ^
list0601.cpp:15:3: error: expected unqualified-id before 'while'
   while (x != end)
   ^
list0601.cpp:20:1: error: expected declaration before '}' token
 }
 ^

When you cannot understand the error messages, look at the first message and the line number it identifies. Search for errors at or near the line number. Ignore the rest of the messages.

On line 5, you may see another error or two. After you fix them, however, a slew of messages still remains. That means you still haven’t found the real culprit (which is on line 4). A different compiler (clang++) is more helpful. It points you to line 4.

list0601.cpp:5:59: error: expected ']'
  std::cout < "This program prints a table of squares. ";
                                                                ^
list0601.cpp:4:1: note: to match this '['
[
^

Once you track down the square bracket and change it to a curly brace, you may get entirely different messages. This is because the substitution of [ for { so thoroughly confuses the compiler, it cannot make any sense of the rest of the program. Correcting that problem straightens out the program for the compiler, but now it may find a whole new set of errors.

Unknown Operator

The input and output operators (>> and <<) are no different from any other C++ operator, such as addition (+), multiplication (*), or comparison (such as >). Every operator has a limited set of allowed operands. For example, you cannot “add” two I/O streams (e.g., std::cin + std::cout), nor can you use an output operator to “write” a number to a string (e.g., "text" << 3).

On line 5, one error is the use of < instead of <<. The compiler cannot determine that you intended to use << and instead issues a message that indicates what is wrong with <. The exact message depends on the compiler, but most likely the message is not something that helps you solve this particular problem. One compiler complains as follows:

list0601.cxx: In function 'int main()':
list0601.cxx:5: error: no match for 'operator<' in 'std::cout < "This programimg
 prints a table of squares.12"'
list0601.cxx:5: note: candidates are: operator<(const char*, const char*) <built-in>
list0601.cxx:5: note:                 operator<(void*, void*) <built-in>

This message notifies you that you are using the wrong operator or the wrong operands. You must determine which one it is.

Once you fix the operator, notice that the compiler does not issue any message for the other mistake, namely, the extraneous semicolon. Strictly speaking, it is not a C++ error. It is a logical error, but the result is a valid C++ program. Some compilers will issue a warning, advising you that line 6 does nothing, which is a hint that you made a mistake. Other compilers will silently accept the program.

The only sure way to detect this kind of mistake is to learn to proofread your code.

Unknown Name

An easy error for a compiler to detect is when you use a name that the compiler does not recognize at all. In this case, accidentally typing the letter l instead of a  semicolon produces the name endl instead of end;. The compiler issues a clear message about this unknown name.

Fix the semicolon, and now the compiler complains about another operator. This time, you should be able to zoom in on the problem and notice that the operator is facing the wrong way (<< instead of >>). The compiler may not offer much help, however. One compiler spews out errors of the following form:

list0601.cxx
list0601.cxx(11) : error C2784: 'std::basic_ostream<char,_Traits> &std::operatorimg
<<(std::basic_ostream<char,_Traits> &,unsigned char)' : could not deduceimg
template argument for 'std::basic_ostream<char,_Elem> &' from 'std::istream'
        C:Program FilesMicrosoft Visual C++ Toolkit 2003includeostream(887)img
: see declaration of 'std::operator'<<''
list0601.cxx(11) : error C2784: 'std::basic_ostream<char,_Traits> &std::operatorimg
<<(std::basic_ostream<char,_Traits> &,unsigned char)' : could not deduceimg
template argument for 'std::basic_ostream<char,_Elem> &' from 'std::istream'
        C:Program FilesMicrosoft Visual C++ Toolkit 2003includeostream(887)img
: see declaration of 'std::operator'<<''

The line number tells you where to look, but it is up to you to find the problem.

Symbol Errors

But now you run into a strange problem. The compiler complains that it does not know what a name means (cout on line 17), but you know what it means. After all, the rest of the program uses std::cout without any difficulty. What’s wrong with line 17 that it causes the compiler to forget?

Small errors can have profound consequences in C++. As it turns out, a single colon means something completely different from a double colon. The compiler sees std:cout as a statement labeled std, followed by the bare name cout. At least the error message points you to the right place. Then it’s up to you to notice the missing colon.

Fun with Errors

After you have fixed all the syntax and semantic errors, compile and run the program, to make sure you truly found them all. Then introduce some new errors, just to see what happens. Some suggestions follow:

Try dropping a semicolon from the end of a statement. What happens?

_____________________________________________________________

_____________________________________________________________

Try dropping a double quote from the start or end of a string. What happens?

_____________________________________________________________

_____________________________________________________________

Try misspelling int as iny. What happens?

_____________________________________________________________

_____________________________________________________________

Now I want you to explore on your own. Introduce one error at a time and see what happens. Try making several errors at once. Sometimes, errors have a way of obscuring one another. Go wild! Have fun! How often does your teacher encourage you to make mistakes?

Now it’s time to return to correct C++ code. The next Exploration introduces the for loop.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset