Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compilation fails with Catch 1.7.0 #806

Closed
nlohmann opened this issue Feb 4, 2017 · 10 comments
Closed

Compilation fails with Catch 1.7.0 #806

nlohmann opened this issue Feb 4, 2017 · 10 comments

Comments

@nlohmann
Copy link

nlohmann commented Feb 4, 2017

Description

JSON for Modern C++ currently uses Catch 1.6.0 for its test suite. Executing make yields only a few warnings which have nothing to do with Catch. So far, so good.

When I update Catch to version 1.7.0, the compilation fails (output below).

(Related to nlohmann/json#445)

Steps to reproduce

  • check out JSON for Modern C++
  • replace file test/thirdparty/catch/catch.hpp with Catch 1.7.0
  • execute make

In particular:

git clone https://github.com/nlohmann/json.git
cd json
rm test/thirdparty/catch/catch.hpp
wget https://github.com/philsquared/Catch/releases/download/v1.7.0/catch.hpp -O test/thirdparty/catch/catch.hpp
make

Extra information

  • Catch version: v1.7.0
  • Operating System: macOS Sierra 10.12.3 (16D32)
  • Compiler+version: clang version 5.0.0 (trunk 292523) (llvm/trunk 292718)

Error output:

[CXX]   src/unit-algorithms.o
[CXX]   src/unit.o
[CXXLD] test-algorithms
[CXX]   src/unit-allocator.o
src/unit-allocator.cpp:31:9: warning: keyword is hidden by macro definition [-Wkeyword-macro]
#define private public
        ^
src/unit-allocator.cpp:62:25: error: unexpected type name 'bad_json': expected expression
        CHECK_THROWS_AS(bad_json j(bad_json::value_t::object), std::bad_alloc);
                        ^
src/unit-allocator.cpp:62:34: error: expected ')'
        CHECK_THROWS_AS(bad_json j(bad_json::value_t::object), std::bad_alloc);
                                 ^
src/unit-allocator.cpp:62:9: note: to match this '('
        CHECK_THROWS_AS(bad_json j(bad_json::value_t::object), std::bad_alloc);
        ^
thirdparty/catch/catch.hpp:10946:48: note: expanded from macro 'CHECK_THROWS_AS'
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
                                               ^
thirdparty/catch/catch.hpp:2283:34: note: expanded from macro 'INTERNAL_CATCH_THROWS_AS'
                static_cast<void>(expr); \
                                 ^
src/unit-allocator.cpp:148:51: error: expected '(' for function-style cast or type construction
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                              ~~~~~~~~~~~~~~~~~~~ ^
thirdparty/catch/catch.hpp:10948:56: note: expanded from macro 'CHECK_NOTHROW'
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
                                                       ^~~~
thirdparty/catch/catch.hpp:2251:31: note: expanded from macro 'INTERNAL_CATCH_NO_THROW'
            static_cast<void>(expr); \
                              ^~~~
src/unit-allocator.cpp:148:51: error: expected ')'
src/unit-allocator.cpp:148:17: note: to match this '('
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                ^
thirdparty/catch/catch.hpp:10948:31: note: expanded from macro 'CHECK_NOTHROW'
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
                              ^
thirdparty/catch/catch.hpp:2251:30: note: expanded from macro 'INTERNAL_CATCH_NO_THROW'
            static_cast<void>(expr); \
                             ^
src/unit-allocator.cpp:148:17: error: extraneous ')' before ';'
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                ^
thirdparty/catch/catch.hpp:10948:31: note: expanded from macro 'CHECK_NOTHROW'
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
                              ^
thirdparty/catch/catch.hpp:2251:35: note: expanded from macro 'INTERNAL_CATCH_NO_THROW'
            static_cast<void>(expr); \
                                  ^
src/unit-allocator.cpp:148:66: error: use of undeclared identifier 'j'
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                                                                 ^
src/unit-allocator.cpp:150:53: error: expected '(' for function-style cast or type construction
                CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc);
                                ~~~~~~~~~~~~~~~~~~~ ^
thirdparty/catch/catch.hpp:10946:74: note: expanded from macro 'CHECK_THROWS_AS'
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
                                                                         ^~~~
thirdparty/catch/catch.hpp:2283:35: note: expanded from macro 'INTERNAL_CATCH_THROWS_AS'
                static_cast<void>(expr); \
                                  ^~~~
src/unit-allocator.cpp:150:53: error: expected ')'
src/unit-allocator.cpp:150:17: note: to match this '('
                CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc);
                ^
thirdparty/catch/catch.hpp:10946:48: note: expanded from macro 'CHECK_THROWS_AS'
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
                                               ^
thirdparty/catch/catch.hpp:2283:34: note: expanded from macro 'INTERNAL_CATCH_THROWS_AS'
                static_cast<void>(expr); \
                                 ^
src/unit-allocator.cpp:161:51: error: expected '(' for function-style cast or type construction
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                              ~~~~~~~~~~~~~~~~~~~ ^
thirdparty/catch/catch.hpp:10948:56: note: expanded from macro 'CHECK_NOTHROW'
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
                                                       ^~~~
thirdparty/catch/catch.hpp:2251:31: note: expanded from macro 'INTERNAL_CATCH_NO_THROW'
            static_cast<void>(expr); \
                              ^~~~
src/unit-allocator.cpp:161:51: error: expected ')'
src/unit-allocator.cpp:161:17: note: to match this '('
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                ^
thirdparty/catch/catch.hpp:10948:31: note: expanded from macro 'CHECK_NOTHROW'
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
                              ^
thirdparty/catch/catch.hpp:2251:30: note: expanded from macro 'INTERNAL_CATCH_NO_THROW'
            static_cast<void>(expr); \
                             ^
src/unit-allocator.cpp:161:17: error: extraneous ')' before ';'
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                ^
thirdparty/catch/catch.hpp:10948:31: note: expanded from macro 'CHECK_NOTHROW'
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
                              ^
thirdparty/catch/catch.hpp:2251:35: note: expanded from macro 'INTERNAL_CATCH_NO_THROW'
            static_cast<void>(expr); \
                                  ^
src/unit-allocator.cpp:161:66: error: use of undeclared identifier 'j'
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                                                                 ^
src/unit-allocator.cpp:163:53: error: expected '(' for function-style cast or type construction
                CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc);
                                ~~~~~~~~~~~~~~~~~~~ ^
thirdparty/catch/catch.hpp:10946:74: note: expanded from macro 'CHECK_THROWS_AS'
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
                                                                         ^~~~
thirdparty/catch/catch.hpp:2283:35: note: expanded from macro 'INTERNAL_CATCH_THROWS_AS'
                static_cast<void>(expr); \
                                  ^~~~
src/unit-allocator.cpp:163:53: error: expected ')'
src/unit-allocator.cpp:163:17: note: to match this '('
                CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc);
                ^
thirdparty/catch/catch.hpp:10946:48: note: expanded from macro 'CHECK_THROWS_AS'
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
                                               ^
thirdparty/catch/catch.hpp:2283:34: note: expanded from macro 'INTERNAL_CATCH_THROWS_AS'
                static_cast<void>(expr); \
                                 ^
src/unit-allocator.cpp:174:51: error: expected '(' for function-style cast or type construction
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                              ~~~~~~~~~~~~~~~~~~~ ^
thirdparty/catch/catch.hpp:10948:56: note: expanded from macro 'CHECK_NOTHROW'
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
                                                       ^~~~
thirdparty/catch/catch.hpp:2251:31: note: expanded from macro 'INTERNAL_CATCH_NO_THROW'
            static_cast<void>(expr); \
                              ^~~~
src/unit-allocator.cpp:174:51: error: expected ')'
src/unit-allocator.cpp:174:17: note: to match this '('
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                ^
thirdparty/catch/catch.hpp:10948:31: note: expanded from macro 'CHECK_NOTHROW'
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
                              ^
thirdparty/catch/catch.hpp:2251:30: note: expanded from macro 'INTERNAL_CATCH_NO_THROW'
            static_cast<void>(expr); \
                             ^
src/unit-allocator.cpp:174:17: error: extraneous ')' before ';'
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                ^
thirdparty/catch/catch.hpp:10948:31: note: expanded from macro 'CHECK_NOTHROW'
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
                              ^
thirdparty/catch/catch.hpp:2251:35: note: expanded from macro 'INTERNAL_CATCH_NO_THROW'
            static_cast<void>(expr); \
                                  ^
src/unit-allocator.cpp:174:66: error: use of undeclared identifier 'j'
                CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));
                                                                 ^
src/unit-allocator.cpp:176:53: error: expected '(' for function-style cast or type construction
                CHECK_THROWS_AS(my_json::json_value j(t), std::bad_alloc);
                                ~~~~~~~~~~~~~~~~~~~ ^
thirdparty/catch/catch.hpp:10946:74: note: expanded from macro 'CHECK_THROWS_AS'
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
                                                                         ^~~~
thirdparty/catch/catch.hpp:2283:35: note: expanded from macro 'INTERNAL_CATCH_THROWS_AS'
                static_cast<void>(expr); \
                                  ^~~~
fatal error: too many errors emitted, stopping now [-ferror-limit=]
1 warning and 20 errors generated.
make[1]: *** [src/unit-allocator.o] Error 1
make: *** [all] Error 2
@horenmar
Copy link
Member

horenmar commented Feb 4, 2017

This is a duplicate of #798 and is caused by the THROWS family of macros now actually depending on received an expression, rather than pasting whatever it gets to a semicolon.

@nlohmann
Copy link
Author

nlohmann commented Feb 4, 2017

This is bitter as it would mean to change a lot of tests...

And how would I express something like

CHECK_NOTHROW(my_json::json_value j(t); clean_up(j));

@horenmar
Copy link
Member

horenmar commented Feb 4, 2017

Is there a reason that it isn't equivalent with clean_up(my_json::json_value(t))?

@nlohmann
Copy link
Author

nlohmann commented Feb 4, 2017

Well, this could maybe fix this issue, but in general it's convenient to have arbitrary code inside CHECK_*.

@nlohmann
Copy link
Author

nlohmann commented Feb 4, 2017

I adjusted my code to work with 1.7.0.

@nlohmann nlohmann closed this as completed Feb 4, 2017
@horenmar
Copy link
Member

horenmar commented Feb 5, 2017

If you can use C++11, then you still can run arbitrary code inside the THROW assertion family, using the same idiom that is used to perform non-trivial initialization of complex const variables.

    REQUIRE_NOTHROW([&](){
        int i = 1;
        int j = 2;
        auto k = i + j;
        if (k == 3) {
            throw 1;
        }
        return true;
    }());

@nlohmann
Copy link
Author

nlohmann commented Feb 5, 2017

Thanks! Only one file was affected so rewriting was not so much work after all.

Just out of curiosity: in the release notes for 1.7.0 you mention nlohmann/json - how did you cope with the compilation errors?

@horenmar
Copy link
Member

horenmar commented Feb 5, 2017

I didn't actually, I benchmarked the tests after merging in the performance branch, but before merging in this change.

@nlohmann
Copy link
Author

nlohmann commented Feb 6, 2017

Just as feedback: It would be great if you'd use Semantic Versioning to make it easier for users to assess whether an update would break existing code.

@philsquared
Copy link
Collaborator

@nlohmann In fact we do (try) to use Semantic Versioning.
We're not breaking any documented interfaces at minor versions (I have a few planned for Catch2, though). But as well as new features we try to hold off fixes that change undocumented interfaces until minor revisions (and even then try to limit their scope). This one seems to have had more of an impact than we anticipated.

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

No branches or pull requests

3 participants