gcc warning "ничего не объявляет - PullRequest
4 голосов
/ 15 марта 2019

Я работаю над обновлением некоторого кода C ++ до C + 11 путем преобразования typedef в использование псевдонимов. Учитывая следующее 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();
}

Я получаю предупреждение, используя объявление using:

warning: declaration ‘enum sample::what’ does not declare anything
     using demo = enum sample::what;
                               ^

хотя код компилируется и выполняется нормально. Компилятор g ++ (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.10) 5.4.0 20160609 Ошибка лежит в компиляторе или во мне?


Спасибо за ответы. Что касается комментариев о структуре C:

  • "S" - SCCE - маленький, поэтому я разместил наименьшую структуру, которая продемонстрировать проблему. Фактическая структура, которую я использую, это "struct proc_event" из Linux / cn_proc.h .

  • Я просто включаю его без "внешнего C" и работает нормально.

Ответы [ 3 ]

5 голосов
/ 15 марта 2019

Проблема в том, что вы создали как тип sample::what, так и член sample::what. Компилятор должен и, по-видимому, разрешает эту проблему, а предупреждение является добрым и явно ошибочным.

Проблема исчезает с:

struct sample {
  enum what {
    FOO,
    BAR
  } what_instance;  //  << Different identifier here
};

и

using demo = sample::what;

Наличие идентификатора типа и идентификатора экземпляра с одинаковым именем в любом случае является плохой идеей по ряду причин. Это сбивает с толку людей, и в этом случае также компилятор. Возможно, компилятор пытается вам что-то сказать; -)

4 голосов
/ 15 марта 2019

Не лежит ли ошибка в компиляторе?

Это ошибка компилятора.Похоже, уже сообщалось: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66159.Проблема воспроизводится, когда в объявлении использования используется разработанный спецификатор имени.В этом случае вам нужно использовать разработанный спецификатор имени, чтобы избежать двусмысленности с членом с таким же именем.

Обходной путь: Вместо этого используйте объявление typedef:

typedef enum sample::what demo;
0 голосов
/ 15 марта 2019

Вы можете просто определить демонстрационный тип для int, потому что enum может быть преобразован во временный int

void usingdemo( ) {
  using demo = int;
  ...
}
...