написание структурного кода, который работает как на C, так и на C ++ - PullRequest
5 голосов
/ 29 октября 2011

Мне известны два возможных способа определения и использования struct s:

#1 
struct person
{
    char name[32];
    int age;
};

struct person dmr = {"Dennis Ritchie", 70};

#2
typedef struct
{
    char name[32];
    int age;
} person;

person dmr = {"Dennis Ritchie", 70};

Интересным свойством первого способа является то, что и тип, и переменная могут иметь одно и то же имя:

struct person person = {"Sam Persson", 50};

Это идиоматично в C?Гарантируется ли работа в C ++?Или есть угловые случаи, о которых мне следует знать?

Обратите внимание, что меня не интересуют чистые ответы C ++ (например, "используйте std::string вместо char[32]").Это вопрос о совместимости C / C ++.

Ответы [ 4 ]

3 голосов
/ 29 октября 2011

struct совместимы между C и C ++, только когда они POD -s.

Я склонен кодировать что-то вроде:

struct person_st { char name[32]; int age; };
typedef struct person_st Person_t;
2 голосов
/ 29 октября 2011

Я заявляю, что они имеют одинаковые имена в пространствах имен тега struct и global identifier:

#ifdef __cplusplus
extern "C" {
#endif

typedef struct person
{
    char name[32];
    int age;
} person;

#ifdef __cplusplus
}
#endif

При использовании, который не требует использования тега struct в переводах C и C ++:

person dmr = {"Dennis Ritchie", 70};

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

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

1 голос
/ 29 октября 2011
struct person person = {"Sam Persson", 50};

Нетрудно использовать один и тот же идентификатор для типа и переменной. В Unix обычно используется сокращенная версия для имени переменной, например: struct stat st, struct timeval tv, ... таким же образом fd является типичным именем переменной дескриптора файла.

0 голосов
/ 29 октября 2011

Я не уверен, что это будет полностью правильно в стандартном C ++, но я протестировал с g++ -pedantic -Wall и не получил ошибок или предупреждений (обратите внимание, что это не обязательно означает, что он полностью стандартный. G ++, даже с -pedantic , не сталкивается с проблемой предупреждения всех нестандартных кодов.) (Кто-то знает спецификацию c ++ достаточно хорошо, чтобы прокомментировать, является ли она на самом деле стандартной или нет?)

вещь с надписью:

struct person person = {...};

означает, что в C ++ person относится и к переменной, и к типу. В C это не было проблемой просто потому, что person не тип (struct person есть). Хотя из контекста, с несколькими тестами, которые я написал с g ++, у компилятора не было проблем с пониманием, когда я запрашиваю переменную и когда для типа, я думаю, что в какой-то момент это может запутаться. Одна запутанная вещь, которую я обнаружил, заключается в том, что если у вас есть:

struct person *person = ...;

затем sizeof(person) возвращает размер переменной, в то время как для получения размера типа вы должны написать sizeof(struct person), что, я могу вас заверить, ни один кодер c ++ не помнит, чтобы написать stuct.

Лучше всего избегать всех видов путаницы. Я обычно делаю это для кода, который можно использовать как в C, так и в C ++:

typedef struct person
{
    ...
} person;

Задание имени для структуры, которая является typedef ed, позволяет программисту использовать person или struct person. Итак, немного гибкости (не говоря уже о том, что вам не нужно менять уже написанный код после typedef с struct.

...