On Thu, Feb 13, 2014 at 11:02 PM, Amir Taaki <genjix@???> wrote:
> Hey, the thing is that clang is broken and isn't implementing C++11 fully.
>
> https://en.wikipedia.org/wiki/C%2B%2B11#Uniform_initialization
>
> It's an error with the compiler, not the code and the double syntax
> actually means something different (create a list with a single element
> initialized to those items). But due to some C++ things it compiles and
> casts it back which isn't what you expect is happening.
>
> I'm hoping clang fixes their compiler, but for now it can work on mac
> using gcc (we've had a few people do it).
I have already researched this, and no, Clang is actually correct! As
it turns out, the std::array type is an aggregate type, which,
according to the standard, provides neither constructor or destructor.
Therefore, initialization works just like old-style C struct
initialization. You need a pair of braces for the class, and another
pair of braces for the array inside. It is similar to initializing
this thing:
class example {
public:
int data[2];
int x;
};
example x = {{0, 0}, 0} /* This is obviously correct */
example x = {0, 0, 0}; /* But C also allowed this! */
example x{{0, 0}, 0} /* C++11 now allows this */
example x{0, 0, 0}; /* C++11 does not allow this, but GCC wrongly accepts it! */
The reason your code worked before is because of a bug in GCC, which
would wrongly accept that last example line. Clang correctly rejects
it.
This is not the only error the patch addresses, but it is the most
common. For example, you used "std::string" in a file that didn't have
an "#include <string>". This only worked by accident with that
particular implementation of the standard library. In another case,
you passed an int into a uniform initializer which expected a size_t.
This is a narrowing conversion, which the C++11 standard does not
allow here (see the Wikipedia article you just linked).
So, this isn't some fly-by-night patch; it's something I've actually
verified according to the standard. The Android Clang has other C++11
problems besides these, but I have solved those by patching the
standard library rather that libbitcoin.
-William