Introduction

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.

Variable-length arrays

GCC allows an array's size to be determined at run time. This,
however, is not standard C++. Furthermore, it is a potential security
hole as an incorrect array size may overflow the stack. If Clang tells
you "variable length arrays are not permitted in C++", here
are some ways in which you can fix it:

replace it with a fixed-size array if you can determine a
reasonable upper bound at compile time; sometimes this is as
simple as changing int size = ...; to const int size
= ...; (if the definition of size is a compile-time
integral constant);

use an std::string instead of a char [];

use std::vector or some other suitable container type;
or

allocate the array on the heap instead using new Type[] -
just remember to delete[] it.

Initialization of non-integral static const data members within a class definition

.../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;
^ ~~~

Only integral 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:

The standard says that unqualified names like func are looked up
when the template is defined, not when it's instantiated. Since
void func(int) was not declared yet when Foo was
defined, it's not considered. The fix is usually to
declare func before Foo.

This is complicated by argument-dependent lookup (ADL),
which is done when unqualified names are called as functions,
like func(x) above. The standard says that ADL is performed
in both places if any of the arguments are type-dependent, like
x is in this example. However, ADL does nothing for builtin
types like int, so the example is still invalid. See
[basic.lookup.argdep] for more information.

Like we said above, unqualified names like
DoThis and DoThat are looked up when the template
Derived 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 Base<T>
because its type depends on the template argument T, so the
standard says we should just ignore it. See [temp.dep]p3 for details.

The fix, as Clang tells you, is to tell the compiler that we want a
class member by prefixing the calls with this->:

void Work(T x) {
this->DoThis(x);
this->DoThat(x);
}

Alternatively, you can tell the compiler exactly where to look:

void Work(T x) {
Base<T>::DoThis(x);
Base<T>::DoThat(x);
}

This works whether the methods are static or not, but be careful:
if DoThis is virtual, calling it this way will bypass virtual
dispatch!

Templates with no valid instantiations

The following code contains a typo: the programmer
meant init() but wrote innit() instead.

template <class T> class Processor {
...
void init();
...
};
...
template <class T> void process() {
Processor<T> processor;
processor.innit(); //
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 Processor<T>. Suppose that later on in
this file the programmer adds an explicit specialization
of Processor, like so:

template <> class Processor<char*> {
void innit();
};

Now the program will work — as long as the programmer only ever
instantiates process() with T = char*! This is why
it's hard, and sometimes impossible, to diagnose mistakes in a
template definition before it's instantiated.

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.