我正在通过将typedef转换为使用别名来将一些C ++代码更新为C + 11。鉴于以下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();
}
Run Code Online (Sandbox Code Playgroud)
我正在使用using声明得到警告:
warning: declaration ‘enum sample::what’ does not declare anything
using demo = enum sample::what;
^
Run Code Online (Sandbox Code Playgroud)
尽管代码可以编译并很好地执行。编译器是g ++(Ubuntu 5.4.0-6ubuntu1〜16.04.10)5.4.0 20160609错误是在编译器中还是在我体内?
感谢您的答复。关于对C结构的评论:
“ S”表示SCCE很小,因此我发布了最小的结构来演示该问题。我使用的实际结构是linux / cn_proc.h中的 “ struct proc_event” 。
我只是将其包括在内,但没有“ extern C”,它工作正常。
问题是您同时创建了类型sample::what和成员sample::what。编译器应该并且显然确实可以解决此问题,并且警告是良性的并且显然是错误的。
问题消失了:
struct sample {
enum what {
FOO,
BAR
} what_instance; // << Different identifier here
};
Run Code Online (Sandbox Code Playgroud)
和:
using demo = sample::what;
Run Code Online (Sandbox Code Playgroud)
在任何情况下,出于多种原因,让类型标识符和实例标识符具有相同的名称都是一个坏主意。这会使人感到困惑,在这种情况下,编译器也会感到困惑。也许编译器试图告诉您一些信息;-)
问题出在编译器上吗?
这是一个编译器错误。似乎已经报告了:https : //gcc.gnu.org/bugzilla/show_bug.cgi?id=66159。当在 using 声明中使用详细的名称说明符时,问题会重现。在这种情况下,您需要使用详细的名称说明符以避免与具有相同名称的成员产生歧义。
解决方法:改用typedef声明:
typedef enum sample::what demo;
Run Code Online (Sandbox Code Playgroud)