gerardw
gerardw

Reputation: 6330

gcc warning "does not declare anything

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:

Upvotes: 5

Views: 2533

Answers (3)

eerorika
eerorika

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

Jisu Hong
Jisu Hong

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

Clifford
Clifford

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

Related Questions