This page documents longer explanations for diagnostics in C/C++ front-ends. Please, feel free to suggest new content in gcc-help mailing list.
TODO
- Add more diagnostics to this list!
Move the info from http://www.network-theory.co.uk/docs/gccintro/gccintro_94.html to this page.
Contents
%D may be used uninitialized [-Wuninitialized]
[ Permalink ]
A variable that has not been initialized is read at some point in the code. Reading a uninitialized variable leads to undefined behaviour. Whether a variable is assigned a value before reading it cannot be decided in general. Depending on the optimization level, the version of GCC and the particular code, GCC may not be able to detect that a variable is actually always initialized and give a false warning. On the other hand, it may be able to detect that the variable is never used apart from uninitialized use and not warn.
See also -Wuninitialized in GCC manual
warning: passing argument %d of %D from incompatible pointer type; note: expected ‘const char **’ but argument is of type ‘char **’
[ Permalink ]
See the C++ FAQ Lite (this question applies to both C and C++):
http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17
C++ FE
error: uninitialized const 'd' [-fpermissive], note: 'const class D' has no user-provided default constructor
[ Permalink ]
1 class C { };
2 class D : public C { };
3 const D d;
As mandated by the C++ standard (8.5 [decl.init], para 9 in C++03, para 6 in C++0x), G++ does not allows objects of const-qualified type to be default initialized unless the type has a user-declared default constructor. Code that fails to compile can be fixed by providing an initializer e.g.
1 const D d = D();
You can use -fpermissive to allow the old, non-conforming behaviour.
error: there are no arguments to 'f' that depend on a template parameter, so a declaration of 'f' must be available
[ Permalink ]
1 template<typename T>
2 struct base
3 {
4 void f();
5 };
6 template<typename T>
7 struct derived : public base<T>
8 {
9 void g() { f(); }
10 };
The C++ standard says (14.6.2 [temp.dep] para 3) that lookup of unqualified names (such as f in the example) does not look in a "dependent base", i.e. a base class which depends on a template parameter. To tell the compiler that f is a member and lookup should include dependent bases, it must be qualified as either this->f() or base<T>::f(). See the C++ templates FAQ or C++ FAQ Lite for further details.
undefined reference to `S::a'
[ Permalink ]
Some people are surprised to get a linker error when using static const members in conditional expressions (i.e. the ?: operator) like so:
1 struct S
2 {
3 static const int a = 1;
4 static const int b = 2;
5 };
6 int main(int argc, char** argv)
7 {
8 return argc > 1 ? S::a : S::b;
9 }
This program is invalid and will fail to link:
/tmp/ccATW9fH.o: In function `main': n.cc:8: undefined reference to `S::a' n.cc:8: undefined reference to `S::b' collect2: error: ld returned 1 exit status
The C++ standard says ([basic.def.odr] 3.2 paragraph 2) "A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression (5.19) and the lvalue-to-rvalue conversion (4.1) is immediately applied." and (paragraph 3) "Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required."
In the example above the lvalue-to-rvalue conversion cannot be applied, because (x?a:b) is an lvalue when a and b are both lvalues of the same type.
The same link error can happen if the static const member is used as an argument to a function which has reference parameters e.g.
1 #include <algorithm>
2 struct S
3 {
4 static const int a = 1;
5 static const int b = 2;
6 };
7 int main(int argc, char** argv)
8 {
9 return std::max(S::a, S::b);
10 }
It should be noted that with optimization enabled the variables may not be referenced, due to inlining or constant propagation, and so linking might succeed, but the program is still technically invalid.
The program can be fixed by providing a definition of the variables and/or by forcing either variable to be converted to an rvalue:
1 struct S
2 {
3 static const int a = 1;
4 static const int b = 2;
5 };
6 const int S::a; // definition
7 const int S::b; // definition
8 int main(int argc, char** argv)
9 {
10 return argc > 1 ? S::a : (int)S::b;
11 }
See also How do I define an in-class constant?
undefined reference to vtable for X
[ Permalink ]
Every polymorphic class requires a virtual table or vtable describing the type and its virtual functions. Whenever possible the vtable will only be generated and output in a single object file rather than generating the vtable in every object file which refers to the class (which might be hundreds of objects that include a header but don't actually use the class.) The cross-platform C++ ABI states that the vtable will be output in the object file that contains the definition of the key function, which is defined as the first non-inline, virtual function declared in the class. If you do not provide a definition for the key function (or fail to link to the file providing the definition) then the linker will not be able to find the class' vtable.
In this example, X::i() is the key function because X::f() is not virtual and X::g() and X::h() are inline (and the key function is never a destructor):
class X {
virtual ~X();
void f();
virtual void g() { }
virtual void h();
virtual void i();
virtual void j();
};
inline void X::h() { }To fix the linker error be sure you have provided a definition for the first non-inline virtual function declared in the class.