Skip to content
This repository has been archived by the owner on Mar 26, 2020. It is now read-only.

MSVC12 Compatibility #2

Open
PaulFreund opened this issue Apr 21, 2014 · 5 comments
Open

MSVC12 Compatibility #2

PaulFreund opened this issue Apr 21, 2014 · 5 comments

Comments

@PaulFreund
Copy link

I really like the library design and would like to use it cross platform. Unfortunately there are a few roadblocks for using it with MSVC12 (VS2013):

  • In json11.cpp the Statics struct can't be initialized because not every member has an initializer
  • Missing noexcept and snprintf
  • The templates that should define implicit constructors for map and vector like objects seem to fail because std::declval() can not be properly resolved and therefore begin can't be found

The first one can be easily fixed by removing the initializers and adding them to the initializer-list in statics():

struct Statics {
    const std::shared_ptr<JsonValue> null;
    const std::shared_ptr<JsonValue> t;
    const std::shared_ptr<JsonValue> f;
    const string empty_string;
    const vector<Json> empty_vector;
    const map<string, Json> empty_map;
};

const Statics & statics() {
    static const Statics s {
        make_shared<JsonNull>(),
        make_shared<JsonBoolean>(true),
        make_shared<JsonBoolean>(false),
        "",
        vector<Json>(),
        map<string, Json>()
    };
    return s;
}

The missing noexcept and sprintf are a bit harder. MSVC12 does not (yet) include them. It is possible to create a preprocessor define for noexcept after the STL header includes (as an error is thrown when trying to define the missing noexcept myself). snprintf can be replaced by _snprintf but unfortunately behaves a bit different (snprintf truncates and always 0-terminates, _snprintf does not 0-terminate if the buffer is too small, also the return values are different which are not used anyway).

I didn't invest enough much time digging in c++11s templating features to understand the third problem yet. A simple solution is to comment out the two constructors but I am sure there is a better solution.

This is an issue for me and I don't know if you are interested in supporting MSVC12 (don't know if this gets better with the next compiler update).

PS: Having this library header only would be really nice too, but that's secondary for now

@j4cbo
Copy link
Contributor

j4cbo commented Apr 21, 2014

Hm, apparently VS2013 is supposed to support declval. But, it looks like I forgot to include in json11.hpp. It could be that declval is accidentally available on gcc/clang because of the other includes, but not in MSVC. Does adding that #include fix it?

json11 only uses snprintf to print numbers, so it should be "safe" to replace all instances of snprintf with sprintf... I'd want to triple-check all the buffer sizes, though.

@PaulFreund
Copy link
Author

I forgot to mention that I already added <type_traits> to check if this is the issue.
Unfortunately not, for reference here is my build output: https://gist.github.com/PaulFreund/11154815

@PaulFreund
Copy link
Author

Just wanted to tell you that I created a copy for me that is header only and compatible with gcc and msvc12 although I currently excluded the two templates that won't compile with msvc12. It's currently very rough and looks like patchwork but it works for now.
Currently I am looking into making the objects mutable so I can spare a few copies.

@malamanteau
Copy link

I was able to get it to compile by adding this right above namespace json11

#ifdef _MSC_VER
    #if _MSC_VER <= 1800 // VS 2013
        #define noexcept
        #define snprintf _snprintf_s
    #endif
#endif

_snprintf_s is identical to the Unix snprintf, and since noexcept isn't supported in VS2013, we just erase them.

Intellisense still doesn't like the fail method, but it seems mostly harmless.

@stevenhoving
Copy link

@retrop we can mimic noexcept with throw()
and I don't think snprintf is equal to _snprintf_s

see:

note:
I know that on paper noexcept != throw() but the way it is used in json11 they are more or less equal.

#ifdef _MSC_VER
    #if _MSC_VER <= 1800 // VS 2013
        #define noexcept throw()
        #define snprintf _snprintf
    #endif
#endif

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants