Value Assert

I'm constructing a value object:

Value sampleLength; 




sampleLength ( (int) 0)


And on Xcode that's just fine, but on Windows I'm triggering an assertation:

Value::Value (ValueSource* const v)  : value (v)
    jassert (v != nullptr);

Any ideas why that happens?  I was hoping to get a cast to a var and hit that constructor.  Maybe I'm running with slightly different version of the JUCE modules ... I'll update on the Mac and see if I get the same error...

Nope. Wasn't the JUCE version.  On the Mac I get this constructor: 

Value::Value (const var& initialValue)  : value (new SimpleValueSource (initialValue))


And on Windows I get cast to a pointer instead... !

What you'd like it to generate is actually value (var ((int) 0)) but for the compiler to do that would require it to add an implicit intermediate cast to var, which it won't do if it can use the other constructor that takes a pointer without the intermediate cast. But I'm really surprised that it wouldn't throw an error or warning when you explicitly cast it to int!

Perhaps a good thing would be for me to add a private dummy constructor that takes a void*, so that in ambiguous cases like this it would choose that one and throw an error because it's inaccessible?

Yep.  I popped the var(..) in there last night to make it confident.  I didn't like the way I got a different result from MSVC and Clang though. 

Clang generated the implict cast. 

I'm not sure why I casted that one explicitly to int in the first place.  May have to go and read the standard again. And perhaps a quick audit of the rest of my code :) 

What version of MSVC are you using (although I doubt they would have changed this behavior as it may have silently broken lots of code).

I'm guessing the problem is that 0 is a special 'maybe an integer value and maybe a pointer' value and MSVC is assuming you meant a pointer as there are fewer levels of indirection to construct the object. I'm not sure if the standard is actually explicit about the precedence here. I couldn't find anything obvious in except for this note which is slightly ambiguous.

4.10 Pointer conversions [conv.ptr]
1 A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type std::nullptr_t.
A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type
and is distinguishable from every other value of object pointer or function pointer type. Such a conversion
is called a null pointer conversion. Two null pointer values of the same type shall compare equal. The
conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the
sequence of a pointer conversion followed by a qualification conversion (4.4). A null pointer constant of
integral type can be converted to a prvalue of type std::nullptr_t. [ Note: The resulting prvalue is not a
null pointer value. — end note ]

A little more searching does reveal this though which suggests MSVC is correct:

Minor update - CTP_Nov2013 gives me a useful "Ambiguous Call To Overloaded Function" error and refuses to compile.  Which is better!

It’s prob not a big deal, but I’m not sure I understand why you’re using CTP_Nov2013 when VS2013 has been officially released for some time? It seems a bit weird to get support for a preview version of a compiler who’s now past the preview stage…

Well, it's a damn fine question. And you've made me double check there's nothing more recent.  But as far as I could tell from the scattered information on Microsoft's site: 

"The Visual C++ Compiler November 2013 CTP contains a preview release of the Visual C++ compiler that adds the following C++11, C++14, and C++/CX features to the set of features already supported by the Visual C++ compiler shipped in Visual Studio 2013".

Is there a later stable version now - there seem to have been a lot of announcements about new Visual Studio's, but I've not figured out what version of the C compiler is sitting underneath them yet....