Reputation: 6330
I'm working on updating some C++ code to C+11 by converting typedef's into using aliases. Given the following SCCE:
#include <iostream>
#include <linux/cn_proc.h>
/**
* Legacy C structure
*/
struct sample {
enum what {
FOO,
BAR
} what;
};
void tdef( ) {
typedef enum sample::what demo;
demo a = sample::FOO;
std::cout << a << std::endl;
}
void usingdemo( ) {
using demo = enum sample::what;
demo a = sample::BAR;
std::cout << a
<< std::endl;
}
int main() {
tdef();
usingdemo();
}
I'm getting a warning using the using declaration:
warning: declaration ‘enum sample::what’ does not declare anything
using demo = enum sample::what;
^
although the code compiles and executes fine. Compiler is g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609 Does the fault lie in the compiler, or in me?
Thanks for the replies. In regards to the comments about the C struct:
The "S" is SCCE is small, so I posted the smallest struct that would demonstrate the issue. The actual struct I'm using is "struct proc_event" from linux/cn_proc.h.
I'm just including it without the "extern C" and it's working fine.
Upvotes: 5
Views: 2533
Reputation: 238391
Does the fault lie in the compiler?
This is a compiler bug. It appears to have been reported already: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66159 . The problem reproduces when an elaborated name specifier is used in a using declaration. In this case, you need to use elaborated name specifier to avoid ambiguity with the member that has the same name.
Workaround: Use typedef
declaration instead:
typedef enum sample::what demo;
Upvotes: 5
Reputation: 724
You could simply define demo type to int because enum can be converted to a temporary int
void usingdemo( ) {
using demo = int;
...
}
Upvotes: -1
Reputation: 93514
The problem is that you have created both a type sample::what
and a member sample::what
. The compiler should, and apparently does resolve this and the warning is benign and apparently erroneous.
The problem goes away with:
struct sample {
enum what {
FOO,
BAR
} what_instance; // << Different identifier here
};
and:
using demo = sample::what;
Having a type identifier and an instance identifier with the same name is a bad idea in any case for a number of reasons. It is confusing to humans, and in this case the compiler also. Perhaps the compiler is trying to tell you something ;-)
Upvotes: 5