Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc warning "does not declare anything

Tags:

c++

gcc

c++11

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.

like image 820
gerardw Avatar asked Mar 15 '19 13:03

gerardw


People also ask

How do I enable warnings in GCC?

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.

How does GCC treat warning errors?

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.

What is werror?

-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.

Which option can be used to display compiler warnings?

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.


2 Answers

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;
like image 158
eerorika Avatar answered Sep 22 '22 16:09

eerorika


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 ;-)

like image 40
Clifford Avatar answered Sep 22 '22 16:09

Clifford