LINUX.ORG.RU

Объявление структур в C


0

0

Как вы предпочитаете объявлять структуры в C?

struct point_t
{
    int x, y;
};

void point_add (struct point_t *p, struct point_t *dp);
typedef struct
{
    int x, y;
}
point_t;

void point_add (point_t *p, point_t *dp);
// C99
typedef struct node_t
{
    void *data;
    struct node_t *next;
}
node_t;

node_t* next_node (node_t *node);

Голосую за третий вариант.

tim239 ★★
()

третий однозначно, ибо, в отличие от второго, позволит объявить указатель в структуре на саму себя, а, в отличие от первого -- краткость при объявлении типа переменной.

Corey
()
Ответ на: комментарий от tailgunner

> Имена типов вида *_t зарезервированы, вообще-то.

Можно подробнее?

> А третий стиль не имеет отношения к C99


Вообще-то имеет. Разделение неймспейсов для структур и типов произошло именно в C99. Обрати внимание, что "node_t" в примере используется и в качестве имени структуры, и в качестве имени типа.

mannaz
() автор топика
Ответ на: комментарий от annoynimous

> Кошерен только первый

а меня всегда напрягало писать struct point_t *p, если можно всегда сделать безболезненно typedef...

Corey
()

Первый. Всё остальное -- моральное извращении, не имеющее права на жизнь.

Глава 5 из /usr/src/linux/Documentation/CodingStyle, в конце концов. Подобное встречается во всех вменяемых стилях оформления кода.

kemm
()

typedef должен быть изгнан из С.

imp ★★
()

Всегда объявляю первым способом.

А необходимость добавлять struct при объявлении переменной -- это даже хорошо (код становится понятнее).

Demon37 ★★★★
()
Ответ на: комментарий от kemm

> Первый. Всё остальное -- моральное извращении, не имеющее права на жизнь.

обоснуйте свое мнение, пожалуйста. А то я, видимо, чего-то недопонимаю

Corey
()
Ответ на: комментарий от true_admin

Потому что если это структура, поля которой доступны, а не аналог void * (как, например, сделано в cURL'е), то код намного прозрачнее без тайпдефов.

kemm
()
Ответ на: комментарий от Corey

Вот есть у нас такое вот:
sometype var;

Что есть var? Структура? union? int? Указатель на что-то?

Если вся работа с var должна идти через специальные функции типа sometype_init()/sometype_destroy()/sometype_dosomething()/et cetera -- тогда и только тогда использование typedef'а оправдано.

В случае "открытой" структуры -- к чертям. Должно быть сразу видно, какой именно это тип.

kemm
()
Ответ на: комментарий от kemm

>код намного прозрачнее без тайпдефов.

typedef struct nodeStruct
{
void *data;
struct nodeStruct *next;
}
nodeStruct;
nodeStruct* next_node (nodeStruct *node);

и в чем же непрозрачность?

Corey
()
Ответ на: комментарий от kemm

>В случае "открытой" структуры -- к чертям. Должно быть сразу видно, какой именно это тип.

ИМХО, тут скорее важна дисциплина и хороший стиль в написании кода. Можно и без тайпдефов нагородить огород.

Corey
()
Ответ на: комментарий от Corey

> ИМХО, тут скорее важна дисциплина и хороший стиль в написании кода. Можно и без тайпдефов нагородить огород.

Можно. Но typedef'ы в случае, кроме указанного, городяд огород автомагически. Либо с самого начала пишем в ООП-стиле, либо никаких тайпдефов.

kemm
()
Ответ на: комментарий от Corey

Когда для всего кода, кроме одного файла, в котором реализуются все функции для работы с этим типом, тип выглядит как void *. В том смысле, что доступа к членам структуры нет.

kemm
()
Ответ на: комментарий от kemm

> Когда для всего кода, кроме одного файла, в котором реализуются все функции для работы с этим типом, тип выглядит как void *

Какой ужоснах. Так еще кто-то делает? Я думал, последние лет 15 используется forward-декларация.

tailgunner ★★★★★
()
Ответ на: комментарий от yoghurt

> Первый и только первый вариант. Остальное - б-гмерзская ересь

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

Corey
()
Ответ на: комментарий от kemm

> Когда для всего кода ... тип выглядит как void *. В том смысле, что доступа к членам структуры нет.

Попахивает норкаманией.

LamerOk ★★★★★
()
Ответ на: комментарий от tailgunner

> Какой ужоснах. Так еще кто-то делает? Я думал, последние лет 15 используется forward-декларация.

Я сказал -- выглядит. В том смысле, что var->something написать нельзя.

kemm
()
Ответ на: комментарий от Corey

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

"Возможности"? Это факт. И это вполне достаточный аргумент.

tailgunner ★★★★★
()
Ответ на: комментарий от kemm

>> Какой ужоснах. Так еще кто-то делает? Я думал, последние лет 15 используется forward-декларация.

> Я сказал -- выглядит

Ты сказал - void *. Это значит, что на место этого параметра можно поставить указатель любого типа, и компилятор на это не пожалуется.

> В том смысле, что var->something написать нельзя.

Что ж, в следующий раз выражайся яснее. И кстати, то, что ты описал - не совсем ООП :) ООП в Си обычно включает в себя создание vtable вручную, и void-указателя на закрытые данные (как в ядре и SOM).

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Ты сказал - void *

К концу рабочего дня я ещё и не такое могу сказать... 8))

kemm
()
Ответ на: комментарий от tailgunner

> "Возможности"? Это факт.

это не факт, а всего лишь вероятность, которой не следует пренебрегать. Я приводил уже пример того, как можно использоваться тайпдеф и при этом не жертвовать читабельностью и прозрачностью.

Corey
()
Ответ на: комментарий от tailgunner

> Думаю, еще раньше - вероятно, вместе с появлением typedef году в 1978

Приходилось видеть кучу legacy-кода в духе:

typedef struct _some_struct
{
...
}
some_struct;

Сомневаюсь, что это было сделано по каким-то исключительно этическим соображениям.

mannaz
() автор топика
Ответ на: комментарий от Corey

> это не факт, а всего лишь вероятность, которой не следует пренебрегать.

Да, пренебрегать 100%-вероятностью неразумно.

> Я приводил уже пример того, как можно использоваться тайпдеф и при этом не жертвовать читабельностью и прозрачностью.


Это:

typedef struct nodeStruct
{
void *data;
struct nodeStruct *next;
}
nodeStruct;
nodeStruct* next_node (nodeStruct *node);

что ли? Писать "nodeStruct *" вместо "struct node *" - в чем профит, 1 пробел? Зачем здесь вообще typedef?

tailgunner ★★★★★
()
Ответ на: комментарий от mannaz

> Сомневаюсь, что это было сделано по каким-то исключительно этическим соображениям.

Ну до недавних пор и ты не знал, что делать одинаковыми тег структуры и typedef-имя можно не только в Си99, так?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Писать "nodeStruct *" вместо "struct node *" - в чем профит, 1 пробел? Зачем здесь вообще typedef?

Самое смешное, что профита тут нет вообще. Количество нажатий ровно то же самое... 8))

kemm
()
Ответ на: комментарий от tailgunner

> в чем профит, 1 пробел?

я просто к тому, что typedef в этом примере не мешает абсолютно, и я не вижу причин для такой лютой ненависти к нему.

Corey
()
Ответ на: комментарий от Corey

>> в чем профит, 1 пробел?

> я просто к тому, что typedef в этом примере не мешает абсолютно

Он ничему никак не помогает, поэтому автоматически попадает под бритву Оккама.

> я не вижу причин для такой лютой ненависти к нему.

Да упаси ТНБ, какая еще ненависть. Я просто предпочитаю стиль Linux kernel, но мнения погут различаться. В GCC typedef применяется.

tailgunner ★★★★★
()
Ответ на: комментарий от Corey

>>Либо с самого начала пишем в ООП-стиле, либо никаких тайпдефов.

>эммм... а что есть ООП-стиль в С?

void *potato = new (Potato, tasty);
void *tomato = new (Tomato, red, fresh);
void *jonny = new (Human, "Jonny");

eat (jonny, potato);
eat (jonny, tomato);

delete (jonny);
delete (tomato);
delete (potato);

Например см. Schreiner A. — Object Oriented Programming in ANSI-C

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

хм.. почитаю на досуге, спс за книгу. А вообще в каких случаях применим такой способ?

Corey
()

Ну , крайности тут ни к чему.
Однозначно видно , что "typedef struct " ООП направленности и бывает весьма полезной при проектировании новых данных и новых составных типов.
Да , "typedef struct " склоняет к подходу "думаем и потом пишем"
- возможно , это и вызывает неприятие.:))

elipse ★★★
()
Ответ на: комментарий от elipse

> "typedef struct " ООП направленности и бывает весьма полезной при проектировании новых данных

> Да , "typedef struct " склоняет к подходу "думаем и потом пишем"

Ааааахренеть......

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Сорри , тут у вас типа бенефис по софистике
не буду мешать и хренейте далее :))

elipse ★★★
()

Первый вариант. Уже привык.

Fen1x
()
Ответ на: комментарий от elipse

> Да , "typedef struct " склоняет к подходу "думаем и потом пишем"

Чо?! (с)

kemm
()
Ответ на: комментарий от tailgunner

Ты такой ироничный. Уточнять в стандартах такие детали мне абсолютно не интересно, я просто всегда использую первый способ из перечисленных и все. Помню, что когда-то давно интересовался данным вопросом, и C99 почему-то всплыл из памяти - возможно, по ошибке. Кстати, в своих книгах K&R, например, всегда использовали различные имена тегов и типов.

mannaz
() автор топика
Ответ на: комментарий от mannaz

> Ты такой ироничный.

Ты чо, обычное чванство.

> я просто всегда использую первый способ из перечисленных и все

Полагаю, что не первый из перечисленных, а первый из сработавших. Почему и как он сработал, тебе "абсолютно не интересно".

> Кстати, в своих книгах K&R, например, всегда использовали различные имена тегов и типов.

Цитата из K&R, 2-е издание (задолго до C99): "Один и тот же идентификатор может использоваться в разных смыслах даже в одной области видимости, если он принадлежит разным пространствам имен. Ниже через точку с запятой перечислены классы объектов, имена которых представляют собой отдельные независимые пространства: объекты, функции, typedef-имена и enum-константы; метки инструкций; теги структур, объединений и перечислений; элементы каждой отдельной структуры или объединения."

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Ты чо, обычное чванство.

Согласен

> Полагаю, что не первый из перечисленных, а первый из сработавших. Почему и как он сработал, тебе "абсолютно не интересно".


Фантазии

> Цитата из K&R...


ВНЕЗАПНО АИ. Победа

mannaz
() автор топика
Ответ на: комментарий от mannaz

>> Ты чо, обычное чванство.

> Согласен

Ну так и говори прямо.

> Фантазии

Экстраполяция. Впрочем, рад буду ошибиться.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Экстраполяция

Ни**евая такая, по одной точке

mannaz
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.