C++11 POD bug

Hi,

I have the following code:

$ cat pod.cc
struct Pod {
  int i;
  Pod() = default;
};

int main(int argc, char **argv) {
  int Size = 1;
  Pod PodArray[Size];
  return 0;
}

I believe that "Pod" should be a POD type in c++11. But when I try to
compile this with clang I get:

$ clang++ --std=c++11 pod.cc
pod.cc:8:15: error: variable length array of non-POD element type 'Pod'
  Pod PodArray[Size];
              ^
1 error generated.

I'm using:

$ clang++ --version
clang version 3.1 (trunk 156916)
Target: x86_64-apple-darwin11.4.0
Thread model: posix

Thanks,
Kal

Your array size specifier is a non-const object making it a variable
length array. VLAs are part of C99. They are not (yet) a part of
standard C++. This thread may be of interest to you
(<http://groups.google.com/group/comp.std.c++/browse_thread/thread/2bfe25800d4961e8/9545494bbb336dfa?pli=1>).

However, you can always use a compile time constant to specify the
size of the array.

struct Pod {
int i;
Pod() = default;
};

int main(int argc, char **argv) {
const int Size = 1; // compile time constant
struct Pod PodArray[Size];
return 0;
}

This compiles fine.

Regards,
Suman

Hi,

You are probably correct about that. But the compiler isn't complaining
about the VLA itself, only that the type is a non-POD. I think "Pod"
should be a POD type in c++11. Here is a more direct example:

$ cat pod.cc
#include <type_traits>
struct Pod {
  int i;
  Pod() = default;
};

static_assert(std::is_pod<Pod>::value, "Pod should be a POD");

$ ~/devel/llvm-install/bin/clang++ --std=c++11 --stdlib=libc++ pod.cc
pod.cc:7:1: error: static_assert failed "Pod should be a POD"
static_assert(std::is_pod<Pod>::value, "Pod should be a POD");
^ ~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

--Kal

As I said, this compiles just fine with my 3.2 (trunk 157155). On
further digging I found that VLAs are in fact supported by clang
(<http://clang.llvm.org/compatibility.html#vla>) as an extension. So,
the following:

$ cat vla.cpp
#include <type_traits>
struct Pod {
int i;
Pod() = default;
};

#if __has_extension(is_pod)
static_assert(std::is_pod<Pod>::value, "Pod should be a POD");
#endif

int main(int argc, char **argv) {
int Size = 1;
struct Pod PodArray[Size];
return 0;
}

compiles fine with std=gnu++0x. You are probably better off with a
check for any type_trait member you are using (see
<http://clang.llvm.org/docs/LanguageExtensions.html#checking_type_traits>).

Can you possibly sync up and see if this problem still exists?

Regards,
Suman

Hi Suman,

I updated to clang 3.2 r157900 and it does work now. Both of my examples
compile without warnings with -std=c++11. Thanks!

Thanks for the interesting links too.

Regards,
Kal

You are probably better off with a
check for any type_trait member you are using (see
<http://clang.llvm.org/docs/LanguageExtensions.html#checking_type_traits>).

std::is_pod (as opposed to __is_pod) is part of the C++11 standard,
so no check for extensions should be required to use it.

Regards,
Nate