ключевое слово struct в параметре функции и const-правильность - PullRequest
4 голосов
/ 29 июня 2011

У меня есть непрозрачный тип в моей библиотеке, определенный как:

typedef struct MyOpaqueType* MyType;  // easier to type for client code

Я не могу передать структуру указатель-на-констату с помощью typedef, поэтому некоторые функции выглядят следующим образом:

void UsePointerToConst ( const struct MyOpaqueType * )

вместо:

void UserPointerToConst( const MyType ) // can't use, is really constant pointer

Итак, у меня есть два вопроса: нужно ли ключевое слово struct в списке параметров только в C?Есть лучший способ сделать это?Должен ли я создать typedef, например:

typedef const struct MyOpaqueType* ConstantMyType; ?

Ответы [ 3 ]

5 голосов
/ 29 июня 2011

Является ли ключевое слово struct в списке параметров необходимым только для C?

Да. См. Ответ Дженса Гастедта.

Есть ли лучший способ сделать это?

Просто typedef структура, а не указатель.Это лучше, потому что

  • вам нужен только один typedef вместо одного для каждого из {MyOpaqueType, MyOpaqueType *, MyOpaqueType const *, MyOpaqueType *const и MyOpaqueType const *const} и всех вариантовс участием restrict (которого нет в C ++),
  • пользователю ясно, что применяется семантика указателя, т. е. передача типа данных на самом деле является вопросом копирования указателя (без проблем с производительностью), пользователименее вероятно, что они забудут очистить после использования, пользователи C ++ могут использовать умные указатели, и
  • это обычное соглашение C (думаю, FILE *).

Там также нет опасности;когда кто-то забывает *, он получает ошибку компилятора.

3 голосов
/ 30 июня 2011

В C ++ предполагается typedef с тем же именем, что и struct, если нет другого идентификатора с этим именем. Так что-то вроде функции stat, которая получает struct stat* в качестве аргумента:

int stat(const char *path, struct stat *buf);

разрешено даже в C ++. (Это пример из реальной жизни.)

Так что вы всегда лучше с предварительными декларациями вроде

typedef struct toto toto;

, который резервирует токен toto в идентификаторе и в пространстве имен структуры. Тогда вы можете объявить интерфейс своей функции для C и C ++. Но не забудьте extern "C", если вы хотите получить к нему доступ также из C.

См. Также: этот ответ для SO и теги struct не являются идентификаторами в C ++ .

2 голосов
/ 29 июня 2011

Вам вообще не нужен typedef в C ++.Просто используйте предварительную декларацию:

struct MyType;

Затем передайте MyType const *, MyType *, MyType const & и т. Д., Как и при необходимости.

...