GCC Error Messages…

…and How-to Solve The Problem

This page has been converted from a Wiki formatted article. If I’ve missed anything in the conversion process, please tell.

Sometimes GCC emits something that can be described as Haiku poems – and you have no clue as to what it really is complaining about. This page is a collection of such gems, their meaning in English and how to solve the problem.

If you run into an error that you feel belongs here, feel free to mail me. I’m using GMail as e8johan.

Compilation Errors

This is a list of compilation errors that you might find yourself trying to interpret in no particular order.

Error: …discards qualifiers

Error message: passing ‘const ClassName’ as ‘this’ argument of ‘virtual void ClassName::methodName()’ discards qualifiers .

You have called a method that isn’t const using a const object ( const ClassName *foo ). Either add const to you method, e.g.

class ClassName

{

public:

void methodName() const;

};

Alternatively, you remove the const from your object, declaring it as ClassName *foo instead of const ClassName *foo .

Sometimes it is possible to solve this issue using const_cast (thanks Witold). Refer to this DevX article for an example of this.

Error: storage size of ‘foo’ isn’t known

Error message: storage size of 'foo' isn't known .

I ran into this problem when using a typedef ed struct as a struct from a function.

typedef struct { ... } Foo;

void function()

{

struct Foo foo;

…

}

The solution is trivial – but hard to spot if you don’t know what to look for.

typedef struct { ... } Foo;

void function()

{

struct Foo foo;

…

}

Error: multiple types in one declaration

Error message: multiple types in one declaration .

You’ve probably forgot to end a class declaration with a semi-colon – ; . The faulting class is not the one that GCC complains about but one of the classes included from the file containing the class declaration GCC nags you about. Locate the faulty class in one of the suspected files, add the semi-colon and try compiling again.

Error: invalid use of undefined type ‘struct Foo’

Error message: invalid use of undefined type ‘struct Foo’ .

It is likely that you are trying to use the class Foo that you’ve forward declared but never included. Simply include the full class declaration for Foo and everything will work.

Error: no matching function for call to ‘FooClass::foo()’

Error message: no matching function for call to 'FooClass::foo()' .

Thanks to Diederik.

If you have implemented and declared the member foo , you are probably trying to use a method from a forward declared class. You need to include the header file containing the declaration of FooClass .

Another variant of this is when you are missing an inherited method. As you are using a forward declared type, GCC cannot tell if FooClass inherits the class implementing foo . A concrete example of this:

chatmaster.cpp:220: error: no matching function for call to ‘ChatMaster::connect(const ContactList*&, const char [35], ChatMaster* const, const char [39])’

/usr/lib/qt3/include/qobject.h:116: note: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*)

/usr/lib/qt3/include/qobject.h:226: note: bool QObject::connect(const QObject*, const char*, const char*) const

Here ContactList is forward declared and GCC cannot tell that it inherits QObject (containing the connect method). You will not get any message telling you that you have forgot to include the header file.

Error: undefined reference to ‘FooClass::foo()’

Error message: undefined reference to 'FooClass::foo()' .

Thanks to Diederik.

You have defined foo in the header file, but not implemented it. Alternately, you’ve used a library function without linking to the needed library.

Error: invalid operands of types `const char[31]’ and `const char[7]’ to binary `operator+’

Error message: invalid operands of types `const char[31]' and `const char[7]' to binary `operator+' .

Thanks to Diederik.

You cannot write "foo" + "bar" , instead write "foo" "bar" (the split could be across a line-break). GCC automatically concatenates strings.

Error: `QValueList’ undeclared (first use this function)

Error message: `QValueList' undeclared (first use this function) .

Thanks to Diederik.

This happens when you write QValueList foo instead of QValueList<type> foo .

Error: cannot call member function `Foo* Foo::instance() const’ without object

Error message: cannot call member function `Foo* Foo::instance() const' without object .

Thanks to Diederik.

You have called instance as a static method, but is was not declared as such.

Errors: non-pointer type, non-aggregate type, cannot convert

Error message: base operand of `->' has non-pointer type `Foo' .

Error message: request for member `bar' in `foo', which is of non-aggregate type `Foo*' .

Error message: cannot convert `Foo' to `Foo*' in initialization .

Thanks to Diederik.

These are all examples of messages that you run into when mixing references, pointers and stack-based variables.

Error: syntax error before `*’ token

Error message: syntax error before `*' token .

Thanks to Diederik.

A class name is unknown. It has not been forward declared, nor included.

Error: `foo’ is not a type

Error message: `foo' is not a type .

You wrote foo.width() when you meant foo->width() .

Error: unable to find a register to spill in class `FOO’

Error message: unable to find a register to spill in class `FOO' .

Thanks to Dexen.

Quoting this thread.

This error message isn’t telling you about an error in your code, it’s telling you about an internal failure (almost certainly a bug) in the compiler. You might be able to work around the compiler bug by re-working your code, but it’s not at all obvious how. You might also try tweaking command-line options, particularly ones related to optimization. A Google search for the error message might be fruitful.

Simon Farnsworth also points out that the cause of this can be inline assembler code: This error can also be caused by inline assembly code. If you have asm() directives in your source (see http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html), check that the input and output operand constraints are correct, and consider relaxing constraints where possible. However, be aware that your inline assembly may not run as fast as intended if you do this.

Error: invalid operands to binary ‘operator<<‘

Error message: invalid operands of types ‘’ and ‘const char [15]’ to binary ‘operator<.

Thanks to Diederik van der Boor.

This message was produced by misspelling cout , for instance:

count << "Hello world!" << endl;

Jonathan Wakely kindly clarified the cause of the error message to me. Apparently, there is a std::count function that confuses the compiler to produce this rather cryptic error message.

Qt Peculiarities

Sometimes Qt’s build system and GCC steps on one anothers toes, resulting in confusion. Many issues can be solved through a make clean && make or just a touch myproject.pro && make .

Using Qt – invalid use of void expression

Error message: invalid use of void expression , while using Qt.

This message can appear if you have forgotten a SIGNAL() or SLOT() macro when calling QObject::connect or a similar function.

Thanks to Loïc Corbasson for this error.

Using Qt – …before ‘protected’

Error message: refers to protected , but at an odd line number, while using Qt.

The signals keyword is really just a define of protected . All signals are protected methods. Hence, the compiler can refer to your signals section when it mentions protected .

Using Qt – …vtable

Error message: complaints about vtable entries.

This can indicate that you are missing a Q_OBJECT macro, or have missed to implement a virtual method. Check for this.

Another potential cause can be that QMake generates Makefiles that can run into this issue when your add or remove signals and slots to classes. The first thing to try is to touch your pro-file, e.g. run touch foo.pro from the command line. If you cannot find an actual problem, and touch does not work, try running make distclean && qmake && make to do a clean rebuild.

Serious Warnings

The warning messages listed below indicates that you might run into serious trouble. As we’re talking about warnings, you will encounter and have to trac down these issues at run-time. A better option is to do something about the warnings.

If you want warnings to stop your compilation, run GCC with the flag -Werror (thanks Jason). Also, see the relevant GCC documentation.

Warning: Control reaches the end of a non-void function

Warning message: Control reaches the end of a non-void function .

There is a way to reach the end of a non-void function without returning something. Add a final return at the end of the function to solve this.

Do not ignore this warning – it is possible to run into really hard to debug problems if you do.

Warning: ‘foo’ is used uninitialized in this function

Warning message: ‘foo’ is used uninitialized in this function

.

You are using foo , even though you have not initialized it. This listing will cause the problem:

int main()

{

int foo, bar;

bar = foo;

foo = 7;

return bar;

}

The solution is to initialize foo before using it. For example, add foo = 0; before bar = foo; . Ignoring this warning can give you random values in a variable, causing the potential bug to appear sometimes, but not always. This can make it very hard to debug.

Warning: cannot pass objects of non-POD type ‘struct std::string’ through ‘…’

Warning message: cannot pass objects of non-POD type 'struct std::string' through '...'; call will abort at runtime .

You are, for instance, trying to print a C++ std::string directly to printf .

std::string foo;

printf( "Foo: %s

", foo );

The result in run-time can be something like Illegal instruction (core dumped) . The proper way to handle the std::string to printf is to use the c_str method:

std::string foo;

printf( "Foo: %s

", foo.c_str() );

Thanks to Mark for this warning.