сильный enum typedef: ошибка clang или стандартная неопределенность c ++ 11? - PullRequest
0 голосов
/ 24 октября 2018

Для такого кода:

typedef enum FooEnum : int FooEnum;
enum FooEnum : int { A = 1, B };

clang (linux / 7.0.0) не сообщает об ошибках [-c -std=c++11 -pedantic], но gcc (linux / 8.2.1) не компилирует его:

g++ -c -std=c++11 -pedantic test2.cpp
test2.cpp:1:28: error: expected ';' or '{' before 'FooEnum'
 typedef enum FooEnum : int FooEnum;
                            ^~~~~~~
test2.cpp:1:28: error: expected class-key before 'FooEnum'
test2.cpp:2:16: error: using typedef-name 'FooEnum' after 'enum'
 enum FooEnum : int { A = 1, B };
                ^~~
test2.cpp:1:28: note: 'FooEnum' has a previous declaration here
 typedef enum FooEnum : int FooEnum;

На самом деле я понятия не имею, зачем использовать typedef для enum в C ++, но вопрос в том, что это ошибка в clang, потому что она принимает неверный код, или это ошибка в стандарте c ++ 11, которая допускает разныереализация?

Обновление: как мне объяснили, первый typedef используется для совместимости с objc ++, чтобы использовать тот же заголовок при компиляции кода c ++ и objc ++.

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Это ошибка clang, вы не можете иметь opaque-enum-объявление после спецификатора typedef.

[dcl.typedef] / 1

Спецификатор typedef не должен объединяться в decl-specier-seq с любым другим типом спецификатора, кроме определяющего типа-спецификатора , [...]

[dcl.type] / 1

определяющий тип-спецификатор:

  • спецификатор типа

  • спецификатор класса

  • спецификатор перечисления

[dcl.enum] / 1

enum-спецификатор:

  • enum-head {enumerator-listopt}

  • enum-head {enumerator-list,}

Таким образом, приведенный ниже код допустим c ++:

typedef enum FooEnum : int { A = 1, B } FooEnum;

, но этот код недопустимc ++:

typedef enum FooEnum : int FooEnum;

Поскольку enum FooEnum:int не является описателем определяющего типа .

0 голосов
/ 24 октября 2018
typedef enum FooEnum : int FooEnum;

Недопустимая строка выше.Я полагаю, вы пытаетесь переслать объявить.Пожалуйста, обратитесь к примеру ниже.

enum class FooEnum;

int fooStar(FooEnum&);

enum class FooEnum : int {
    A =1,
    B
};

int foo(FooEnum fooEnum) {
  return static_cast<int>(fooEnum);
}

int fooStar(FooEnum& fooEnum) {
  return static_cast<int>(fooEnum);
}
...