|
|
|
|
13.2 Compiler error messages
`variable' undeclared (first use in this function)
-
In C and C++ variables must be declared before they can be used. This
error message indicates that the compiler has encountered a variable
name which does not have a corresponding declaration. It can be caused
by a missing declaration, or a typing error in the name. Variable names
are case-sensitive, so
foo and Foo represent different
variables. To keep the output short, only the first use of an
undeclared variable is reported.
Example:
int
main (void)
{
int i;
j = 0; /* undeclared */
return j;
}
The variable j is not declared and will trigger the error `j'
undeclared .
parse error before `...'
-
syntax error
-
These error messages occur when the compiler encounters unexpected
input, i.e. sequences of characters which do not follow the syntax of
the language. The error messages can be triggered by a missing close
bracket, brace or semicolon preceding the line of the error, or an
invalid keyword.
Example:
#include <stdio.h>
int
main (void)
{
printf ("Hello ") /* missing semicolon */
printf ("World!\n");
return 0;
}
There is a missing semicolon after the first call to printf ,
giving a parse error .
parse error at end of input
-
This error occurs if the compiler encounters the end of a file
unexpectedly, such as when it has parsed an unbalanced number of opening
and closing braces. It is often caused by a missing closing brace
somewhere.
Example:
#include <stdio.h>
int
main (void)
{
if (1) {
printf ("Hello World!\n");
return 0; /* no closing brace */
}
An additional closing brace is needed in this program to prevent the
error parse error at end of input .
warning: implicit declaration of function `...'
-
This warning is generated when a function is used without a prototype
being declared. It can be caused by failing to include a header file,
or otherwise forgetting to provide a function prototype.
Example:
int
main (void)
{
printf ("Hello World!\n"); /* no header */
return 0;
}
The system header file 'stdio.h' is not included, so the prototype
for printf is not declared. The program needs an initial line
#include <stdio.h> .
unterminated string or character constant
-
This error is caused by an opening string or character quote which does
not have a corresponding closing quote. Quotes must occur in matching
pairs, either single quotes
'a' for characters or double quotes
"aaa" for strings.
Example:
#include <stdio.h>
int
main (void)
{
printf ("Hello World!\n); /* no closing quote */
return 0;
}
The opening quote for the string in this program does not have a
corresponding closing quote, so the compiler will read the rest of the
file as part of the string.
character constant too long
-
In C and C++ character codes are written using single quotes, e.g.
'a' gives the ASCII code for the letter a (67), and '\n'
gives the ASCII code for newline (10). This error occurs if single quotes
are used to enclose more than one character.
Example:
#include <stdio.h>
int
main (void)
{
printf ('Hello World!\n'); /* wrong quotes */
return 0;
}
The program above confuses single-quotes and double-quotes. A sequence
of characters should be written with double quotes, e.g. "Hello
World!" . This same problem occurs in the following C++ program,
#include <iostream>
int
main (void)
{
std::cout << 'Hello World!\n'; // wrong quotes
return 0;
}
This error can also occur if the forward slash and backslash are
confused in an escape sequence, e.g. using '/n' instead of
'\n' . The sequence /n consists of two separate
characters, '/' and 'n'.
Note that according to the C standard there is no limit on the length of
a character constant, but the value of a character constant that
contains more than one character is implementation-defined. Recent
versions of GCC provide support multi-byte character constants, and
instead of an error the warnings multiple-character character
constant or warning: character constant too long for its type
are generated in this case.
warning: initialization makes integer from pointer without a cast
-
This error indicates a misuse of a pointer in an integer context.
Technically, it is possible to convert between integer and pointer
types, but this is rarely needed outside system-level applications.
More often, this warning is the result of using a pointer without
dereferencing it (e.g. writing
int i = p instead of int i
= *p ).
This warning can also occur with char and char * types,
since char is an integer type.
Example:
int
main (void)
{
char c = "\n"; /* incorrect */
return 0;
}
The variable c has type char , while the string "\n"
evaluates to a const char * pointer (to a 2-byte region of memory
containing the ASCII value for newline followed by a zero byte '\0' ,
since strings are null-terminated). The ASCII code for newline can be
found using char c = '\n';
Similar errors can occur with misuse of the macro NULL ,
#include <stdlib.h>
int
main (void)
{
int i = NULL; /* incorrect */
return 0;
}
In C, the macro NULL is defined as ((void *)0) in
'stdlib.h' and should only be used in a pointer context.
dereferencing pointer to incomplete type
-
This error occurs when a program attempts to access the elements of
struct through a pointer without the layout of the struct being declared
first. In C and C++ it is possible to declare pointers to structs
before declaring their struct layout, provided the pointers are not
dereferenced--this is known as forward declaration.
Example:
struct btree * data;
int
main (void)
{
data->size = 0; /* incomplete type */
return 0;
}
This program has a forward declaration of the btree struct
data . However, the definition of the struct is needed before the
pointer can be dereferenced to access individual members.
warning: unknown escape sequence `...'
-
This error is caused by an incorrect use of the escape character in a
string. Valid escape sequences are:
| \n newline
| \t tab
|
| \b backspace
| \r carriage return
|
| \f form feed
| \v vertical tab
|
| \a alert (bell)
|
The combinations \\ , \' , \" and \? can be
used for individual characters. Escape sequences can also use octal
codes \0 --\377 and hexadecimal codes
\0x00 --\0xFF .
Example:
#include <stdio.h>
int
main (void)
{
printf ("HELLO WORLD!\N");
return 0;
}
The escape sequence \N in the program above is invalid--the
correct escape sequence for a newline is \n .
warning: suggest parentheses around assignment used as truth value
-
This warning highlights a potentially serious error, using the assignment
operator '=' instead of the comparison operator '==' in the
test of a conditional statement or other logical expression. While the
assignment operator can be used as part of a logical value, this is rarely
the intended behavior.
Example:
#include <stdio.h>
int
main (void)
{
int i = 0;
if (i = 1) { /* = should be == */
printf ("unexpected result\n");
}
return 0;
}
The test above should be written as if (i == 1) , otherwise the
variable i will be set to 1 by the evaluation of the if
statement itself. The operator '=' both assigns and returns the
value of its right-hand side, causing the variable i to be
modified and the unexpected branch taken. Similar unexpected results
occur with if (i = 0) instead of if (i == 0) ,
except that in this case the body of the if statement would
never be executed.
This warning is suppressed if the assignment is enclosed in additional
parentheses to indicate that it is being used legitimately.
warning: control reaches end of non-void function
-
A function which has been declared with a return type, such as
int or double , should always have a return
statement returning a value of the corresponding type at all
possible end points--otherwise its return value is not well-defined.
Functions declared void do not need return statements.
Example:
#include <stdio.h>
int
display (const char * str)
{
printf ("%s\n", str);
}
The program above reaches the end of the display function, which has
a return type of int , without a return statement. An
additional line such as return 0; is needed.
When using gcc the main function of a C program must
return a value of type int (the exit status of the program). In
C++ the return statement can be omitted from the main
function--the return value of the C++ main function defaults
to 0 if unspecified.
warning: unused variable `...'
-
warning: unused parameter `...'
-
These warnings indicate that a variable has been declared as a local
variable or in the parameters of a function, but has not been used
anywhere. An unused variable can be the result of a programming error,
such as accidentally using the name of a different variable in place of
the intended one.
Example:
int
foo (int k, char * p)
{
int i, j;
j = k;
return j;
}
In this program the variable i and the parameter p are
never used. Note that unused variables are reported by -Wall ,
while unused parameters are only shown with -Wall -W .
warning: passing arg of ... as ... due to prototype
-
This warning occurs when a function is called with an argument of a
different type from that specified in the prototype. The option
-Wconversion is needed to enable this warning. See
the description of -Wconversion in section 3.5 Additional warning options for an example.
warning: assignment of read-only location
-
warning: cast discards qualifiers from pointer target type
-
warning: assignment discards qualifiers ...
-
warning: initialization discards qualifiers ...
-
warning: return discards qualifiers ...
-
These warnings occur when a pointer is used incorrectly, violating a
type qualifier such as
const . Data accessed through a pointer
marked as const should not be modified, and the pointer itself
can only be assigned to other pointers that are also marked
const .
Example:
char *
f (const char *s)
{
*s = '\0'; /* assigns to read-only data */
return s; /* discards const */
}
This program attempts to modify constant data, and to discard the
const property of the argument s in the return value.
initializer element is not a constant
-
In C, global variables can only be initialized with constants, such as
numeric values,
NULL or fixed strings. This error occurs if a
non-constant value is used.
Example:
#include <stdio.h>
FILE *stream = stdout; /* not constant */
int i = 10;
int j = 2 * i; /* not constant */
int
main (void)
{
fprintf (stream, "Hello World!\n");
return 0;
}
This program attempts to initialize two variables from other variables.
In particular, the stream stdout is not required to be a constant
by the C standard (although on some systems it is a constant). Note
that non-constant initializers are allowed in C++.
|
|
|