Static assertion failure in core on compilation with 64 bit (EDIT: VS with /Zp4)


#1

When compiling the juce core in a 64bit project with VisualStudio 2013 (admittedly not boilerplated with rejucer though), I get a static assertion failure from juce_String.cpp at this line:

static_jassert (sizeof (EmptyString) == sizeof (StringHolder));

I believe the problem has to do with the alignment specifier in the Atomic<int> (which is used in StringHolder, but not EmptyString):

   #if JUCE_64BIT
    JUCE_ALIGN(8)
   #else
    JUCE_ALIGN (4)
   #endif

I did specify the JUCE_64BIT specifier: that makes no difference.

Taking the alignment macros out entirely makes it compile, but I don't know what consequences that has.

I used the master branch and the version Jule's committed to last evening - the code in question is there for a year now though, I don't think this is a new issue.

Maybe there's some additional build options I didn't set?


#2

Loads of people, including me, have been using VS2013 for a long time now, and everyone will have used that code without any trouble. So it must be some setting that you've customised in your project, but I've no idea what!


#3

The demo project can't be built targetting x64 with struct member alignment set to 4 bytes (option /Zp4 under code generation and using VS 2012 this time).

This option was set in the After Effects plugin sample project I was using.


#4

A safer way to make JUCE compile appears to simply use Atomic<int> in the EmptyString like this:

//==============================================================================
// (Mirrors the structure of StringHolder, but without the atomic member, so can be statically constructed)
struct EmptyString
{
    Atomic<int> refCount;
    size_t allocatedBytes;
    String::CharPointerType::CharType text;
};
static const EmptyString emptyString = { static_cast<Atomic<int> >(0x3fffffff), sizeof (String::CharPointerType::CharType), 0 };

The comment suggests that this should have trouble compiling, but it does compile for me.


#5

The point that the comment is making is that although it would obviously compile with Atomic<int>, having a class there instead of a primitive means that the compiler may choose to initialise it using a function, which can create order-of-initialisation problems. But by using a primitive type, the exe's startup image would just contain the raw memory image of it, so would safe to use from any compile unit, even during other static initialisers.