Подтвердить что ты не робот

Соглашение об именах при использовании STRUCT в C

Я изучаю C и обнаруживаю, что кто-то определил структуру, ее имя структуры _ перед ней. Это мой первый раз видел, может кто-нибудь рассказать мне немного больше об этом? Почему кто-то будет использовать _aStructName вместо aStructName, каковы преимущества?

struct _huffmanNode {
    int value;
    uint32_t frequency;

    int hasChild;
    struct _huffmanNode *child[2];

    struct _huffmanNode *next;
};

Аналогично, я нахожу, что кто-то использует это соглашение об именах в следующем коде:

typedef struct HuffCode_ {

unsigned char      used;
unsigned short     code;
unsigned char      size;

} HuffCode;
4b9b3361

Ответ 1

В коде пользователя нет пользы, это просто уродливо. Во втором примере HuffCode_ даже не требуется, так как тип struct уже назван typedef.

Единственными местами, где это может быть полезно, являются:

  • Когда StructName уже используется, StructName_ дает другое имя (но вы действительно должны иметь лучшее имя).
  • Идентификаторы в стандартной библиотеке C, которые не определены стандартом, не должны конфликтовать с идентификаторами кода пользователя. Поэтому авторы C-библиотек используют префикс _ в надежде, что пользователи не будут его использовать. К сожалению, некоторые пользователи делают.
  • В очень старых компиляторах может оказаться полезным присвоить struct другое имя, чем используется в typedef. Вам нужно как typedef, так и другое имя, если вы создаете связанную структуру (пример).

Ответ 2

Много времени в прямом C, люди любят печатать свои структуры, чтобы они не выглядели такими уродливыми. Поэтому они называют структуру самой уродливой, а typedef - чистой. Обычно соглашение, которое я видел в мире GNU, это:

typedef struct mytype_t
{
    int field;
    char field2;
} mytype;

Ответ 3

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

struct MyStruct;
typedef struct MyStruct MyStruct;

будет сталкиваться странным образом, потому что теги struct и typedef имеют одно и то же имя. Это неверно, по крайней мере, в C. В C имя структуры считается тегом, тогда как typedef создает имя типа. Они живут в двух разных пространствах имен и не будут сталкиваться. На мой взгляд, для тега структуры теряет смысл, так как typedef, если вы вообще используете typedef. В C вы всегда должны ссылаться на структуру с ключевым словом struct. Например, если вы определяете

struct MyStruct;

но не введите typedef, тогда следующее недопустимо:

void myfunction()
{
  MyStruct var;   /* compiler error: MyStruct is not defined. */
  struct MyStruct var2; /* this is OK, MyStruct is a valid name for a struct. */
}

Если вы хотите определить переменные (или аргументы) типа MyStruct в C, вы должны указать typedef:

typedef struct MyStruct MyStruct;

void myfunction2()
{
  MyStruct var;  /* this is ok now */
  struct MyStruct var2; /* this is still ok too */
}

В этом втором примере var и var2 имеют один и тот же тип, хотя это не очевидно. Действительно, если typedef были изменены, у них не было бы более одного типа. Остерегайтесь этого! Это может вызвать некоторые интересные ошибки при определении типов.

Однако в С++ определение структуры по существу создает неявный typedef, так что оба вышеописанных фрагмента кода компилируются. В С++ нет, по существу, никакой разницы между именем структуры (или тегом) и именем типа. Это, на мой взгляд, еще одна серьезная причина назвать два одинаковых способа, особенно если вы ожидаете, что ваш C-модуль может быть использован некоторыми С++ -кодерами в какой-то момент.

Ответ 4

Я использую вариант второго примера:

typedef struct huffcode {
... } HuffCode;

Ответ 5

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

struct __foo_s {
  int bar;
};

где-то рядом с верхней частью файла, поэтому я просто знаю, какие сигнатуры функций безопасны для изменения. Если мой проект называется abc, и я хочу опубликовать __foo_s для публики, я бы поставил

struct abc_foo_s {
  int bar;
};

в заголовке, и всякий раз, когда я сталкиваюсь с сигнатурой с struct abc_foo_s*, я был бы в два раза осторожнее при изменении этого.

Просто вопрос личного вкуса, в конце концов, я считаю.