В чем причина typedef против struct/union/enum, разве не может быть только одно пространство имен?

В C, если я объявлю struct/union/enum:

struct Foo { int i ... }

когда я хочу использовать свою структуру, мне нужно указать тег:

struct Foo foo;

Чтобы обойти это требование, я должен использовать псевдоним для своей структуры, используя typedef:

typedef struct Foo Foo;

Почему бы не иметь все типы/структуры/что угодно в одном и том же «пространстве имен» по умолчанию? Каково обоснование решения о необходимости тега объявления при каждом объявлении переменной (если только typedef'd) ???

Многие другие языки не делают этого различия, и кажется, что ИМХО это только добавляет дополнительный уровень сложности.


person clyfe    schedule 09.10.2010    source источник
comment
Не сложнее, чем '#define LPFOO *FOO', все о месте :( Однако в большинстве кодов, которые я видел, структурам Foo и Foo даются разные имена (например, Foo_t и Foo или что у вас есть), даже если они находятся в разных «пространства имен» компилятору.   -  person    schedule 09.10.2010
comment
Не могли бы вы указать, какие есть другие языки, кроме C++?   -  person Arun    schedule 09.10.2010
comment
@Arun: C# и Java не помещают свои типы в отдельное пространство имен тегов (но они могут находиться в истинном пространстве имен, включая глобальное пространство имен, которое немного отличается от пространства имен тегов, введенного C)   -  person paercebal    schedule 06.12.2014


Ответы (3)


Структуры/записи были очень ранним дополнением к B до C, сразу после того, как Деннис Ритчи добавил базовую «типизированную» структуру. Я считаю, что исходный синтаксис struct вообще не имел тега, для каждой переменной вы сделали анонимный struct:

struct {
    int  i;
    char a[5];
} s;

Позже тег был добавлен, чтобы разрешить повторное использование макета структуры, но на самом деле он не считался настоящим «типом». Кроме того, удаление struct/union сделает синтаксический анализ невозможным:

/* is Foo a union or a struct? */
Foo { int i; double x; };
Foo s;

или сломать парадигму 'синтаксис объявления имитирует синтаксис выражения', столь фундаментальную для C.

Я подозреваю, что typedef был добавлен намного позже, возможно, через несколько лет после «рождения» C.

Аргумент «C был языком самого высокого уровня в то время». не кажется правдой. Алгол-68 предшествует ему и имеет записи как собственные типы. То же самое верно и для Паскаля.

Если вы хотите узнать больше об истории C, вы можете найти Ритчи. "Развитие языка Си" интересное чтение.

person schot    schedule 11.10.2010
comment
Я действительно не понимаю, какое это имеет отношение к вопросу. ОП спрашивает, почему им нужно говорить struct Foo foo вместо Foo foo при объявлении переменной, а не определении типа. - person detly; 11.10.2010
comment
@detly: я хотел предоставить некоторый контекст, но я мог бы быть более точным: Потому что теги не начинались как настоящие типы, и чтобы убедиться, что «синтаксис объявления имитирует синтаксис выражения» остается возможным. > - person schot; 11.10.2010
comment
хорошо, это имеет больше смысла. Я никогда не думаю о правиле «синтаксис объявления имитирует синтаксис выражения», кроме типов указателей. - person detly; 11.10.2010

Ну, другие языки также обычно поддерживают пространства имен. С нет.

Вероятно, это не причина, но имеет смысл иметь хотя бы это естественное пространство имен.

person Šimon Tóth    schedule 09.10.2010

Интересный вопрос! Вот мои мысли.

Когда был создан C, над языком ассемблера существовала небольшая абстракция. Были FORTRAN, B и другие, но когда появился C, это был, возможно, язык самого высокого уровня из существующих. Его цель состояла в том, чтобы предоставить функциональные возможности и синтаксис, достаточно мощные для создания и обслуживания операционной системы, и это удалось замечательно.

Подумайте, что в то время перенос системы на новую платформу означал переписывание и адаптацию компонентов к языку ассемблера платформы. С выпуском C в конечном итоге дело дошло до переноса компилятора C и перекомпиляции существующего кода.

Вероятно, тогда было преимуществом то, что сам синтаксис языка заставлял вас различать типы, которые могли поместиться в регистр, и типы, которые не могли.

Синтаксис языка сильно изменился с тех пор, и большинство вещей, которые мы привыкли видеть в современных языках, отсутствуют в C. Определяемые пользователем пространства имен — лишь одно из них, и я не думаю, что концепция «синтаксического сахара» "тогда даже существовал. Вернее, C был вершиной синтаксического сахара.

Мы окружены такими вещами. Я имею в виду, взгляните на свою клавиатуру: почему у нас есть клавиша PAUSE/BREAK? Не думаю, что я нажимал эту клавишу годами.

Это наследие того времени, когда это имело смысл.

person slezica    schedule 09.10.2010
comment
Я регулярно нажимаю клавишу PAUSE/BREAK. Для меня наиболее распространенным использованием является прерывание компиляции или взлом с помощью отладчика. - person mrduclaw; 10.10.2010