2013-07-29 11 views
5

В библиотеке FreeImagePlus, в FreeImage.h, есть забавный #define, который, кажется, создает typedef и enum с таким же названием:Typedef и перечисление с таким же именем?

#define FI_ENUM(x)  typedef int x; enum x 

Это расширяется препроцессором код, как:

typedef int FREE_IMAGE_FILTER; 
enum FREE_IMAGE_FILTER { 
FILTER_BOX = 0, 
FILTER_BICUBIC = 1, 
[...] 

Что это делает? Является ли законным иметь typedef и одноименное имя enum? И не является enum совместимым с int в любом случае? Почему FreeImage делает это?

ответ

6

Имена структур, союзов и перечислений живут в собственном пространстве имен. Вот почему вы можете объявить переменную /enum с тем же именем, что и фактическое struct/union/enum.

И это не имя полного enum (например, для enum X я имею в виду X), который должен быть совместим с целым числом, это имена внутри перечисления.

+0

Спасибо, не знали об пространствах имен. Тем не менее, где помогает «typedef int»? Есть ли какой-нибудь код, который не работает без него? – sleske

+0

@sleske. В общем, это не нужно, вы также можете сделать 'typedef enum X {...} X;' Если не выполняются операции с переменными типа 'X', которые не могут быть выполнены для типов перечисления. –

0

Цитирование C99 N1256 draft 6.2.1 "Сфера идентификаторов":

Идентификатор может обозначать объект; функция; тег или член структуры, объединения или перечисления; имя typedef; имя ярлыка; имя макроса; или макропараметр.

, что означает, что в:

typedef int id; 

id является идентификатором.

А из 6.2.3 «пространств имен идентификаторов»:

НАЧАТЬ QUOTE

Если более чем одна декларации определенного идентификатора видна в любой точке в единице трансляции, синтаксический контекст устраняет неоднозначность использования которые относятся к различным объектам. Таким образом, существуют отдельные пространства имен для различных категорий идентификаторов, а именно:

  • наименования этикеток (однозначно обозначены синтаксисом декларации и использования этикеток);
  • теги структур, союзов и перечислений (неоднозначно, следуя любым ключевым словам struct, union или enum);
  • члены структур или союзов; каждая структура или объединение имеет отдельное пространство имен для своих членов (неоднозначно по типу выражения, используемого для доступа к элементу через оператор. или ->);
  • все другие идентификаторы, называемые обычными идентификаторами (объявляются в обычных деклараторах или как константы перечисления).

Конец цитаты

Так в:

typedef int id; 
enum id {ID0}; 
  • первого id представляет собой обычный идентификатор
  • вторая идентификатор тега

оба могут сосуществовать миролюбиво.

С другой стороны, мы не могли бы сделать что-то вроде:

typedef int id; 
int id; 

, потому что оба были бы обычные идентификаторы.

 Смежные вопросы

  • Нет связанных вопросов^_^