2010-03-17 04:31:53 +00:00
< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
< html >
< head >
< META http-equiv = "Content-Type" content = "text/html; charset=ISO-8859-1" / >
< title > Clang - C++ Compatibility< / title >
< link type = "text/css" rel = "stylesheet" href = "menu.css" / >
< link type = "text/css" rel = "stylesheet" href = "content.css" / >
< style type = "text/css" >
< / style >
< / head >
< body >
<!-- #include virtual="menu.html.incl" -->
< div id = "content" >
<!-- ======================================================================= -->
< h1 > Clang's C++ Compatibility< / h1 >
<!-- ======================================================================= -->
< ul >
< li > < a href = "#intro" > Introduction< / a > < / li >
< li > < a href = "#vla" > Variable-length arrays< / a > < / li >
< li > < a href = "#init_static_const" > Initialization of non-integral static const data members within a class definition< / a > < / li >
2010-03-17 07:10:56 +00:00
< li > < a href = "#dep_lookup" > Unqualified lookup in templates< / a > < / li >
< li > < a href = "#dep_lookup_bases" > Unqualified lookup into dependent bases of class templates< / a > < / li >
2010-06-15 23:50:08 +00:00
< li > < a href = "#declaration_ordering" > Template uses of a function must either find the function by ADL or come after the declaration of the function< / a > < / li >
2010-06-02 01:26:32 +00:00
< li > < a href = "#undep_incomplete" > Incomplete types in templates< / a > < / li >
2010-04-09 01:07:07 +00:00
< li > < a href = "#bad_templates" > Templates with no valid instantiations< / a > < / li >
2010-03-17 04:31:53 +00:00
< li > < a href = "#default_init_const" > Default initialization of const variable of a class type requires user-defined default constructor< / a > < / li >
< / ul >
<!-- ======================================================================= -->
< h2 id = "intro" > Introduction< / h2 >
<!-- ======================================================================= -->
< p > Clang strives to strictly conform to the C++ standard. That means
it will reject invalid C++ code that another compiler may accept.
This page helps you decide whether a Clang error message means a
C++-conformance bug in your code and how you can fix it.< / p >
<!-- ======================================================================= -->
< h2 id = "vla" > Variable-length arrays< / h2 >
<!-- ======================================================================= -->
2010-05-22 16:17:30 +00:00
< p > GCC and C99 allow an array's size to be determined at run
time. This extension is not permitted in standard C++. However, Clang
supports such variable length arrays in very limited circumstances for
compatibility with GNU C and C99 programs:< / p >
< ul >
< li > The element type of a variable length array must be a POD
("plain old data") type, which means that it cannot have any
user-declared constructors or destructors, base classes, or any
members if non-POD type. All C types are POD types.< / li >
2010-05-23 19:57:01 +00:00
< li > Variable length arrays cannot be used as the type of a non-type
template parameter.< / li > < / ul >
2010-05-22 16:17:30 +00:00
< p > If your code uses variable length arrays in a manner that Clang doesn't support, there are several ways to fix your code:
2010-03-17 04:31:53 +00:00
< ol >
2010-05-22 16:17:30 +00:00
< li > replace the variable length array with a fixed-size array if you can
determine a
2010-03-17 04:31:53 +00:00
reasonable upper bound at compile time; sometimes this is as
simple as changing < tt > int size = ...;< / tt > to < tt > const int size
= ...;< / tt > (if the definition of < tt > size< / tt > is a compile-time
integral constant);< / li >
< li > use an < tt > std::string< / tt > instead of a < tt > char []< / tt > ;< / li >
< li > use < tt > std::vector< / tt > or some other suitable container type;
or< / li >
< li > allocate the array on the heap instead using < tt > new Type[]< / tt > -
2010-03-17 05:46:21 +00:00
just remember to < tt > delete[]< / tt > it.< / li >
2010-03-17 04:31:53 +00:00
< / ol >
<!-- ======================================================================= -->
< h2 id = "init_static_const" > Initialization of non-integral static const data members within a class definition< / h2 >
<!-- ======================================================================= -->
The following code is ill-formed in C++'03:
< pre >
class SomeClass {
public:
static const double SomeConstant = 0.5;
};
const double SomeClass::SomeConstant;
< / pre >
Clang errors with something similar to:
< pre >
.../your_file.h:42:42: error: 'SomeConstant' can only be initialized if it is a static const integral data member
static const double SomeConstant = 0.5;
^ ~~~
< / pre >
Only < i > integral< / i > constant expressions are allowed as initializers
within the class definition. See C++'03 [class.static.data] p4 for the
details of this restriction. The fix here is straightforward: move
the initializer to the definition of the static data member, which
must exist outside of the class definition:
< pre >
class SomeClass {
public:
static const double SomeConstant;
};
const double SomeClass::SomeConstant< b > = 0.5< / b > ;
< / pre >
2010-03-17 07:10:56 +00:00
Note that the forthcoming C++0x standard will allow this.
2010-03-17 04:31:53 +00:00
<!-- ======================================================================= -->
2010-03-17 07:10:56 +00:00
< h2 id = "dep_lookup" > Unqualified lookup in templates< / h2 >
2010-03-17 04:31:53 +00:00
<!-- ======================================================================= -->
Some versions of GCC accept the following invalid code:
< pre >
2010-03-17 07:10:56 +00:00
template < typename T> struct Foo {
void Work(T x) {
func(x);
}
};
...
void func(int x);
...
template struct Foo< int> ; // or anything else that instantiates Foo< int> ::Work
< / pre >
The standard says that unqualified names like < tt > func< / tt > are looked up
when the template is defined, not when it's instantiated. Since
< tt > void func(int)< / tt > was not declared yet when < tt > Foo< / tt > was
defined, it's not considered. The fix is usually to
declare < tt > func< / tt > before < tt > Foo< / tt > .
2010-03-17 04:31:53 +00:00
2010-03-17 07:10:56 +00:00
< p > This is complicated by < i > argument-dependent lookup< / i > (ADL),
which is done when unqualified names are called as functions,
like < tt > func(x)< / tt > above. The standard says that ADL is performed
in both places if any of the arguments are type-dependent, like
< tt > x< / tt > is in this example. However, ADL does nothing for builtin
types like < tt > int< / tt > , so the example is still invalid. See
[basic.lookup.argdep] for more information.
<!-- ======================================================================= -->
< h2 id = "dep_lookup_bases" > Unqualified lookup into dependent bases of class templates< / h2 >
<!-- ======================================================================= -->
Some versions of GCC accept the following invalid code:
< pre >
template < typename T> struct Base {
void DoThis(T x) {}
2010-03-17 04:31:53 +00:00
static void DoThat(T x) {}
};
2010-03-17 07:10:56 +00:00
template < typename T> struct Derived : public Base< T> {
2010-03-17 04:31:53 +00:00
void Work(T x) {
DoThis(x); // Invalid!
DoThat(x); // Invalid!
}
};
< / pre >
2010-03-17 07:10:56 +00:00
Clang correctly rejects it with the following errors
(when < tt > Derived< / tt > is eventually instantiated):
2010-03-17 04:31:53 +00:00
< pre >
2010-03-17 07:10:56 +00:00
my_file.cpp:8:5: error: use of undeclared identifier 'DoThis'
2010-03-17 04:31:53 +00:00
DoThis(x);
^
this->
2010-03-17 07:10:56 +00:00
my_file.cpp:2:8: note: must qualify identifier to find this declaration in dependent base class
2010-03-17 04:31:53 +00:00
void DoThis(T x) {}
^
2010-03-17 07:10:56 +00:00
my_file.cpp:9:5: error: use of undeclared identifier 'DoThat'
2010-03-17 04:31:53 +00:00
DoThat(x);
^
this->
2010-03-17 07:10:56 +00:00
my_file.cpp:3:15: note: must qualify identifier to find this declaration in dependent base class
2010-03-17 04:31:53 +00:00
static void DoThat(T x) {}
< / pre >
2010-03-17 07:10:56 +00:00
Like we said < a href = "#dep_lookup" > above< / a > , unqualified names like
< tt > DoThis< / tt > and < tt > DoThat< / tt > are looked up when the template
< tt > Derived< / tt > is defined, not when it's instantiated. When we look
up a name used in a class, we usually look into the base classes.
However, we can't look into the base class < tt > Base< T> < / tt >
because its type depends on the template argument < tt > T< / tt > , so the
standard says we should just ignore it. See [temp.dep]p3 for details.
< p > The fix, as Clang tells you, is to tell the compiler that we want a
class member by prefixing the calls with < tt > this-> < / tt > :
2010-03-17 04:31:53 +00:00
< pre >
void Work(T x) {
< b > this-> < / b > DoThis(x);
< b > this-> < / b > DoThat(x);
}
< / pre >
2010-03-17 07:10:56 +00:00
Alternatively, you can tell the compiler exactly where to look:
2010-03-17 04:31:53 +00:00
< pre >
void Work(T x) {
2010-03-17 07:10:56 +00:00
< b > Base< T> < / b > ::DoThis(x);
2010-03-17 04:31:53 +00:00
< b > Base< T> < / b > ::DoThat(x);
}
< / pre >
2010-03-17 07:10:56 +00:00
This works whether the methods are static or not, but be careful:
if < tt > DoThis< / tt > is virtual, calling it this way will bypass virtual
dispatch!
2010-06-15 23:50:08 +00:00
<!-- ======================================================================= -->
< h2 id = "declaration_ordering" > Template uses of a function must either find the function by ADL or come after the declaration of the function< / h2 >
<!-- ======================================================================= -->
< p > For example, gcc-4.4 accepts the following code:< / p >
< pre >
#include < iostream>
#include < utility>
#include < vector>
template< typename T>
void Dump(const T& value) {
std::cout < < value < < "\n";
}
template< typename T, typename U>
std::ostream& operator< < (std::ostream& out, const std::pair< T, U>& i) {
return out < < '(' < < i.first < < ", " < < i.second < < ")";
}
namespace ns {
struct Data {};
}
std::ostream& operator< < (std::ostream& out, ns::Data) {
return out < < "Some data";
}
void Use() {
Dump(std::make_pair(3, 4.5));
Dump(ns::Data());
Dump(std::vector< const char*>(1, "Hello World"));
}
template< typename T>
std::ostream& operator< < (std::ostream& out, const std::vector< T>& vec) {
out < < '[';
for (size_t i = 0, size = vec.size(); i != size; ++i) {
if (i != 0)
out < < ", ";
out < < vec[i];
}
return out < < ']';
}
< / pre >
< p > while clang, following the rules in < tt > [temp.dep.candidate]< / tt >
complains:< / p >
< pre >
< b > test.cc:7:13: < span class = error > error:< / span > invalid operands to binary expression ('ostream' (aka 'basic_ostream< char>') and 'std::pair< int, double> const')< / b >
std::cout < < value < < "\n";
< span class = caret > ~~~~~~~~~ ^ ~~~~~< / span >
< b > test.cc:24:3: note:< / b > in instantiation of function template specialization 'Dump< std::pair< int, double> >' requested here
Dump(std::make_pair(3, 4.5));
< span class = caret > ^< / span >
< b > test.cc:7:13: < span class = error > error:< / span > invalid operands to binary expression ('ostream' (aka 'basic_ostream< char>') and 'ns::Data const')< / b >
std::cout < < value < < "\n";
< span class = caret > ~~~~~~~~~ ^ ~~~~~< / span >
< b > test.cc:25:3: note:< / b > in instantiation of function template specialization 'Dump< ns::Data>' requested here
Dump(ns::Data());
< span class = caret > ^< / span >
< b > test.cc:7:13: < span class = error > error:< / span > invalid operands to binary expression ('ostream' (aka 'basic_ostream< char>') and 'std::vector< char const *, std::allocator< char const *> > const')< / b >
std::cout < < value < < "\n";
< span class = caret > ~~~~~~~~~ ^ ~~~~~< / span >
< b > test.cc:26:3: note:< / b > in instantiation of function template specialization 'Dump< std::vector< char const *, std::allocator< char const *> > >' requested here
Dump(std::vector< const char*>(1, "Hello World"));
< span class = caret > ^< / span >
3 errors generated.
< / pre >
< p > The fix is to< / p >
< ol > < li > Add a declaration before the use of the function, or
< li > Move the definition to before the use of the function, or
< li > Move the function into the same namespace as one of its
arguments. (Note that it still needs to be declared before the
template is < i > instantiated< / i > .)
< / ol >
< pre >
#include < iostream>
#include < utility>
#include < vector>
template< typename T> // Fix 1.
std::ostream& operator< < (std::ostream& out, const std::vector< T>& vec);
template< typename T, typename U> // Fix 2.
std::ostream& operator< < (std::ostream& out, const std::pair< T, U>& i) {
return out < < '(' < < i.first < < ", " < < i.second < < ")";
}
template< typename T>
void Dump(const T& value) {
std::cout < < value < < "\n";
}
namespace ns {
struct Data {};
std::ostream& operator< < (std::ostream& out, Data) { // Fix 3.
return out < < "Some data";
}
}
void Use() {
Dump(std::make_pair(3, 4.5));
Dump(ns::Data());
Dump(std::vector< const char*>(1, "Hello World"));
}
template< typename T>
std::ostream& operator< < (std::ostream& out, const std::vector< T>& vec) {
out < < '[';
for (size_t i = 0, size = vec.size(); i != size; ++i) {
if (i != 0)
out < < ", ";
out < < vec[i];
}
return out < < ']';
}
< / pre >
2010-06-02 01:26:32 +00:00
<!-- ======================================================================= -->
< h2 id = "undep_incomplete" > Incomplete types in templates< / h2 >
<!-- ======================================================================= -->
The following code is invalid, but compilers are allowed to accept it:
< pre >
class IOOptions;
template < class T> bool read(T & value) {
IOOptions opts;
return read(opts, value);
}
class IOOptions { bool ForceReads; };
bool read(const IOOptions & opts, int & x);
template bool read< > (int & );
< / pre >
The standard says that types which don't depend on template parameters
must be complete when a template is defined if they affect the
program's behavior. However, the standard also says that compilers
are free to not enforce this rule. Most compilers enforce it to some
extent; for example, it would be an error in GCC to
write < tt > opts.ForceReads< / tt > in the code above. In Clang, we feel
that enforcing the rule consistently lets us provide a better
experience, but unfortunately it also means we reject some code that
other compilers accept.
< p > We've explained the rule here in very imprecise terms; see
[temp.res]p8 for details.
2010-04-09 01:07:07 +00:00
<!-- ======================================================================= -->
< h2 id = "bad_templates" > Templates with no valid instantiations< / h2 >
<!-- ======================================================================= -->
The following code contains a typo: the programmer
meant < tt > init()< / tt > but wrote < tt > innit()< / tt > instead.
< pre >
template < class T> class Processor {
...
void init();
...
};
...
template < class T> void process() {
Processor< T> processor;
processor.innit(); // < -- should be ' init ( ) '
...
}
< / pre >
Unfortunately, we can't flag this mistake as soon as we see it: inside
a template, we're not allowed to make assumptions about "dependent
types" like < tt > Processor< T> < / tt > . Suppose that later on in
this file the programmer adds an explicit specialization
of < tt > Processor< / tt > , like so:
< pre >
template < > class Processor< char*> {
void innit();
};
< / pre >
Now the program will work — as long as the programmer only ever
instantiates < tt > process()< / tt > with < tt > T = char*< / tt > ! This is why
it's hard, and sometimes impossible, to diagnose mistakes in a
template definition before it's instantiated.
< p > The standard says that a template with no valid instantiations is
ill-formed. Clang tries to do as much checking as possible at
definition-time instead of instantiation-time: not only does this
produce clearer diagnostics, but it also substantially improves
compile times when using pre-compiled headers. The downside to this
philosophy is that Clang sometimes fails to process files because they
contain broken templates that are no longer used. The solution is
simple: since the code is unused, just remove it.
2010-03-17 04:31:53 +00:00
<!-- ======================================================================= -->
< h2 id = "default_init_const" > Default initialization of const variable of a class type requires user-defined default constructor< / h2 >
<!-- ======================================================================= -->
If a < tt > class< / tt > or < tt > struct< / tt > has no user-defined default
constructor, C++ doesn't allow you to default construct a < tt > const< / tt >
instance of it like this ([dcl.init], p9):
< pre >
class Foo {
public:
// The compiler-supplied default constructor works fine, so we
// don't bother with defining one.
...
};
void Bar() {
const Foo foo; // Error!
...
}
< / pre >
To fix this, you can define a default constructor for the class:
< pre >
class Foo {
public:
Foo() {}
...
};
void Bar() {
const Foo foo; // Now the compiler is happy.
...
}
< / pre >
< / div >
< / body >
< / html >