Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Test fails with anonymous-enum-as-int? #98

Closed
PureAbstract opened this Issue · 5 comments

2 participants

@PureAbstract

Hi Phil - finally got around to trying Catch, and stumbled across this problem:

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

enum {
    Value0,
    Value1,
    Value2,
};
typedef unsigned Value;

TEST_CASE( "Failure/mode", "Unexpected failure mode" )
{
    Value v0 = Value0;
    Value v1 = Value1;
    Value v2 = Value2;
    REQUIRE( v0 == Value0 );
    REQUIRE( v1 == Value1 );
    REQUIRE( v2 == Value2 ); // Fails here
}

The final REQUIRE fails with:
AnonymousEnum.mm:18: v2 == Value2 failed for: 2 == true

A workaround is to cast Value2 to (unsigned)Value2

This is a "Simplest Thing That Can Possibly Work^h^h^h^hFail" version; my actual test case is using NSStreamStatus

Cheers,
Andy

@philsquared
Owner

Wow that's a weird one!

And I can't reproduce it.
What compiler are you using?
I presume this is in an Objective-C context (since you mentioned NSStreamStatus)?

Are you using the single include version of CATCH?
How recent is it? Did you just download it?

@philsquared
Owner

Actually I just reproduced it!
It works for me with LLVM, but if I put it into GCC mode I get the result you're seeing!
If I name the enum it works ok again.

It seems to be treating the unnamed enum as a local type (which can't be used to instantiate C++ templates).
If I pass a value of that enum directly to a template it doesn't compile (with GCC). However within the require there's an overload that takes a bool. The enum seems to be matching that (hence the weird message).

I'm not sure whether the issue is with CATCH or the compiler at this point. Further investigation needed.
In the meantime I'd suggest either: don't use instances of unnamed enums, or, use LLVM.
You can also wrap the expression in parentheses (which forces it to be evaluated before being passed on to the templates).
All those workarounds are a bit sucky, but I'll have to work out if there's anything better I can do.

@philsquared
Owner

Just checked. Unnamed enums are not local types, but the same rule wrt templates applied - ie you can't instantiate with them. I think LLVM may be assuming C++11 rules, which do allow them, IIRC.
Doesn't help, but clears that one up, at least

@philsquared
Owner

Yes - here's the backup for C++11 allowing unnamed types to instantiate templates:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm

@PureAbstract

Speedy work indeed!

As you've figured out, I'm using gcc (4.2) in objective-c++ mode
single-include version of Catch @ 78372d0, dated 2012-06-06 08:06:40 (which is the current head as I write this)

Sounds like it's a compiler issues. I can't do much about not using anonymous enums (since I'm using Cupertino flavoured headers ;-), but at least there's a workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.