Active the Error List window
Click 1st error, then press F1 for help.|
Error C1075 Error C2059 Error C2065 Error C2143 Error C2146 |
Error C2228 Error C2236 Error C2275 Error C2440 Error C2601 |
Error C2628 Error C2819 Error C3861 Error C4430 Error LNK2001 Error LNK2019 |
void main() {
x = 5; // ERROR: 'x': undeclared identifier; need to declare x.
int y = yearr(); // ERROR: 'yearr': identifier not found; maybe year()?
}
Error C2275: 'type': illegal use of this type as an expression
struct point { int x,y; };
int x = point.x; // ERROR: 'point' is not a variable, it's a variable *type*
Error C2164: syntax error ';' before identifier 'name'innt instead of int)
and so the compiler got confused:
struct point { int x,y; };
Point p; // ERROR: compiler doesn't know what 'Point' is; should be 'point'
Error C2440: cannot convert from 'type1' to 'type2'a=b when a and b
are of completely different types:
int x = 0; // OK: 0 is understood to be of type 'int' int* y = 0; // OK: 0 is understood to be of type 'int*' (null) char* z = 0; // OK: 0 is understood to be of type 'char*' (null) x = y; // ERROR: cannot convert from 'int*' to 'int' y = x; // ERROR: cannot convert from 'int' to 'int*' y = z; // ERROR: cannot convert from 'char*' to 'int*'This can also happen when passing function arguments or return values:
int year() {
return "2010"; // ERROR: cannot convert from 'const char [4]' to 'int'
}
void draw_point(point p);
void main()
{
int x = 50;
draw_point(x); // ERROR: cannot convert parameter 1 from 'int' to 'point'
}
Another cause is forgetting to use () when calling a function.
This mistake gives a really confusing error message, but is easy to fix if you spot it.
Supposing we have function year():
int y = year; // ERROR: cannot convert from 'int (*)()' to 'int'Error C2628: 'type1' followed by 'type2' is illegal
;' in a struct/class declaration:
struct point { int x,y; }; // OK
struct point { int x,y; } // ERROR: declaration of 'point' must end with ;
Error C2143: missing ';' before '}';' after the last statement inside some { } block:
struct point { int x,y }; // ERROR: declaration of 'x,y' must end with ;
int five() { return 5 } // ERROR: forgot to put ; after 5
if (ok) { cout << "ok" } // ERROR: forgot to put ; after "ok"
Error C1075: end of file found before the left brace '{' was matched{ than }, meaning you forgot to close one of your scopes:
int min(int a, int b) {
if (a < b) {
return a;
return b;
} // compiler sees '}' as matching (i.e. closing) the 'if' block
void main() { // ERROR C2601: compiler sees main() as though inside min()
}
// ERROR C1705: end of file before all '{' were matched
Error C2059: syntax error} somewhere:
int min(int a, int b) {
if (a < b)
return a;
} // oops! this '}' closes the function!
return b; // ERROR: syntax error 'return'
} // ERROR: syntax error '}'
Error C4430: missing type specifier
x = 5; // ERROR: should be declared as "int x = 5;"
five() { return 5; } // ERROR: should be declared as "int five()"
Or you have an extra '}' somewhere and the compiler is confused about scope;
see Error C2059.
Error C2819: type does not have overloaded member 'operator ->'->' when you should've used '.'.
point p; p->x = 0; // ERROR: 'p' is not a pointer, so use 'p.x'Error C2228: left of '.name' must have class/struct/union
.' when you should've used '->'.
point* q = &p; q.x = 0; // ERROR: 'q' is a pointer, so use 'q->x'Error LNK2001/LNK0019: unresolved external symbol 'name'
void hello(); // Declare 'hello' function (often in a .h file)
void main() {
hello(); // ERROR: unresolved external symbol 'void hello(void)'
}
void hallo() { // Rename this 'hello' and it will work, as long as
cout << "hello"; // it appears in any .cpp file in to your project
}
Oy! Writing to address 0 is an "Access violation."
Code that crashes on delete. Can you spot the bug?b has 10 items,
then the first item is b[0]
and the last item is b[9].
If your code somehow asks for b[-1] or b[10], then you have
a dangerous bug. When you see b[i]
you should think "that's the (i+1)'th item in the array".
Uninitialized variableint grades[80]; // grades[0..79] = ??? int i = 0, j; // i = 0, j = ??? int grade_i = grades[i]; // DANGER: grade_i = ??? int grade_j = grades[j]; // CRASH: grade_j = grades[???]Reading
grades[0] isn't technically a crash — you own that memory so you
can read it if you like — but the debugger will still warn you that it's
a stupid thing to do. Reading grades[j] is a real crash because
it accesses some random memory.
Pointers are a type of variable that should always be initialized.
If you don't have something to point at right away, always initialize to NULL (zero):
int* ptr; // ptr = ???
if (ptr != 0) // Useless test, since ptr is probably not 0
*ptr = 123; // CRASH: *(???) = 123
Uninitialized data member
class array_of_int {
public:
void push_back(int item) { m_items[m_size++] = item; }
private:
int m_size;
int m_items[50]; // Stores up to 50 integers
};
void main() {
array_of_int temperatures;
temperatures.push_back(22); // CRASH: grades.m_items[???] = 22
}
The solution here is to provide a constructor that initializes m_size:
class array_of_int {
public:
array_of_int() { m_size = 0; } // Fixed the bug!
...
NULL pointer dereference
ptr1 points to x, ptr2 is NULL. int* ptr = 0; *ptr = 123; // CRASH: tried to write '123' to memory location 0Dangling pointer
void main()
{
int* grades = new int[50]; // 'grades' becomes valid pointer.
delete [] grades; // 'grades' becomes dangling pointer! Careful...
for (int i = 0; i < 50; ++i) // You can accidentally read/write a dangling pointer
grades[i] = 0;
} // Until program exits -- heap corruption detected!
== (test equality)
and not just = (assign value). Here's an example of such a bug:
int speed = 0;
if (speed = 0)
cout << "speed is zero!"; // This line never runs!
Modifying a list within a loop
void erase_perfect_grades(array_of_int& grades)
{
for (int i = 0; i < grades.size(); ++i) // Buggy loop
if (grades[i] == 100)
grades.erase(i);
}
If grades contained intitial values {85,100,100,60}
then after returning it will contain {85,100,60}.
Why wasn't the other 100 erased? Because erase(i) shifts
all the items after i downwards, so that item i+1
now occupies slot i and so on. Correct code is as follows:
void erase_perfect_grades(array_of_int& grades)
{
for (int i = 0; i < grades.size(); ) // Correct loop
if (grades[i] == 100)
grades.erase(i);
else
++i; // Only do ++i if item is not erased
}
Copied object when you should've referenced it
struct rectangle { int x,y,wd,ht; };
void grow_rect(rectangle rect, int amount) // Grow size of a rectangle by 'amount'
{
rect.wd += amount;
rect.ht += amount;
}
void main()
{
rectangle mario_hitbox = { 0,0,50,100 };
grow_rect(mario_hitbox,10); // Doesn't modify mario_hitbox!
draw_rect(mario_hitbox); // Draws rect of size 50x100, not 60x110.
}
The above code could be fixed by replacing rectangle rect with a
reference rectangle& rect or, with a few more changes, a pointer
rectangle* rect would work too. See lecture notes on references for more examples.
T represents a class name (e.g. string, array_of_int, etc).
Make sure none of the "wrong" examples appear in your assignments, or you'll lose marks!
The list will grow throughout the course, so check back before each assignment.
Creating & destroying variableswrong
{
T obj;
obj.~T(); // Destructed once.
} // Destructed twice!
|
right
{
T obj;
} // Destruct once.
|
Never call a destructor explicitly! Variables on stack are destructed
when they go out of scope (example above), and variables in heap are destructed by
the delete function. | |
wrong
T* p = new T[5]; // p[0..4] constructed. delete p; // Only p[0] destructed! |
right
T* p = new T[5]; delete[] p; // p[0..4] destructed. |
If you allocate an array of items with new T[] then
you must deallocate with delete[]. In other words, C++ unfortunately makes
you responsible for remembering which pointers point to a single object via new T and
which point to an array of objects via new T[]. | |
wrong
ptr = 0; // Memory leak! delete ptr; // Does nothing. |
right
delete ptr; // Free memory. |
The above example assumes that ptr points to a single object and
we want to destroy the object (i.e. free the memory it uses). To destruct the object and free its memory,
just call delete. You can point ptr at something else
afterwards, if you like (e.g. to NULL). | |