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.
This warning is enabled by -Wall or -Wextra . Warn when a #pragma directive is encountered that is not understood by GCC. If this command-line option is used, warnings are even issued for unknown pragmas in system header files. This is not the case if the warnings are only enabled by the -Wall command-line option.
The warning is emitted only with --coverage enabled. By default, this warning is enabled and is treated as an error. -Wno-coverage-invalid-line-number can be used to disable the warning or -Wno-error=coverage-invalid-line-number can be used to disable the error.
-Werror= Make the specified warning into an error. The specifier for a warning is appended; for example -Werror=switch turns the warnings controlled by -Wswitch into errors.
You can use a #pragma warning directive to control the level of warning that's reported at compile time in specific source files. Warning pragma directives in source code are unaffected by the /w option.
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;
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 ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With