# Clang's C++ Compatibility

- Introduction
- Variable-length arrays
- Initialization of non-integral static const data members within a class definition
- Unqualified lookup in templates
- Unqualified lookup into dependent bases of class templates
- Default initialization of const variable of a class type requires user-defined default constructor

## 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:

1. 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);
2. use an `std::string` instead of a `char []`;
3. use `std::vector` or some other suitable container type; or
4. 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

The following code is ill-formed in C++'03:

    class SomeClass {
     public:
      static const double SomeConstant = 0.5;
    };

    const double SomeClass::SomeConstant;

Clang errors with something similar to:

    .../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:

    class SomeClass {
     public:
      static const double SomeConstant;
    };

    const double SomeClass::SomeConstant = 0.5;

Note that the forthcoming C++0x standard will allow this.

## Unqualified lookup in templates

Some versions of GCC accept the following invalid code:

    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

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.

## Unqualified lookup into dependent bases of class templates

Some versions of GCC accept the following invalid code:

    template <typename T> struct Base {
      void DoThis(T x) {}
      static void DoThat(T x) {}
    };

    template <typename T> struct Derived : public Base<T> {
      void Work(T x) {
        DoThis(x);  // Invalid!
        DoThat(x);  // Invalid!
      }
    };

Clang correctly rejects it with the following errors (when `Derived` is eventually instantiated):

    my_file.cpp:8:5: error: use of undeclared identifier 'DoThis'
        DoThis(x);
        ^
        this->
    my_file.cpp:2:8: note: must qualify identifier to find this declaration in dependent base class
      void DoThis(T x) {}
           ^
    my_file.cpp:9:5: error: use of undeclared identifier 'DoThat'
        DoThat(x);
        ^
        this->
    my_file.cpp:3:15: note: must qualify identifier to find this declaration in dependent base class
      static void DoThat(T x) {}

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!

## Default initialization of const variable of a class type requires user-defined default constructor

If a `class` or `struct` has no user-defined default constructor, C++ doesn't allow you to default construct a `const` instance of it like this ([dcl.init], p9):

    class Foo {
     public:
      // The compiler-supplied default constructor works fine, so we
      // don't bother with defining one.
      ...
    };

    void Bar() {
      const Foo foo;  // Error!
      ...
    }

To fix this, you can define a default constructor for the class:

    class Foo {
     public:
      Foo() {}
      ...
    };

    void Bar() {
      const Foo foo;  // Now the compiler is happy.
      ...
    }