Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 Enum forward causes "underlying type mismatch"

I'm working in C++11 and including an h file implemented in C++03. In the h file I'm including there's an enum Foo defined. I want to declare a forward to it in code.h and use it in code.cpp:

header.h:

enum Foo {A=1};

code.h:

enum Foo : int; // also tried : unsigned int, long, short, unsigned short, char, unsigned char
void bar(Foo foo);

code.cpp:

#include header.h
void bar(Foo foo) { }

This is the error I get when I compile (tested g++ 4.8.5 and g++ 5.3.1):

In file included from code.cpp:2:0:
header.h:1:6: error: underlying type mismatch in enum ‘enum Foo’
 enum Foo {A=1};
      ^
In file included from code.cpp:1:0:
code.h:3:12: error: previous definition here
 enum Foo : int;

I can fix this error if I change header.h to:

enum Foo : int {A=1};

But I don't own that header and can't change it. Taking the error at face value, it sounds like all I need to know is what type g++ uses for enums which don't specify underlying type, then use that type in my forward.

Even this simple example doesn't work :

#include <iostream>
#include <string>
#include <type_traits>

enum Foo {A=1};
enum Foo : unsigned; // : std::underlying_type<Foo>::type also doesn't work

int main()
{

  std::cout << "Hello, world\n";
}
like image 668
ytoledano Avatar asked Mar 13 '17 15:03

ytoledano


1 Answers

There doesn't seem to be any way of doing this, even if you specify the exact same underlying type that the compiler would have chosen for your C++03-style enum.

Example: compiling the following code...

enum Foo { A=1 };
cout << typeid(typename std::underlying_type<Foo>::type).name();

...on Coliru and demangling via c++filt will print "unsigned int" both with g++ and clang++.

Even if you specify unsigned int as the explicit underlying type of your Foo forward declaration, both compilers will complain.

enum Foo : unsigned int;
void bar(Foo);

enum Foo {A=1};

main.cpp:8:6: error: enumeration previously declared with fixed underlying type
enum Foo {A=1};
     ^
main.cpp:5:6: note: previous declaration is here
enum Foo : unsigned int;
     ^

This is because both the forward declaration and the "real" enum declaration need to have the same explicit underlying type, even if you manage to "guess" what the compiler would have chosen for you.


tl;dr: you can only forward-declare an enum if both the forward-declaration and the real declaration have the same explicitly specified underlying type.

like image 50
Vittorio Romeo Avatar answered Sep 23 '22 15:09

Vittorio Romeo