2013-09-06 2 views
2

Глядя на заголовочный файл OpenCL я вижу:C/C++ опережающее объявление в ЬурейеМ

typedef struct _cl_context * cl_context; 

Я понимаю, что cl_context является указателем на вперед объявленной структуру _cl_context.

С точки зрения дизайнера библиотеки, какие преимущества делают это снова:

typedef struct _cl_context cl_context; 

это просто так API вызовы могут принимать cl_context вместо cl_context*? Но если это так, почему бы не просто сделать:

typedef void *cl_context; 

ответ

5

Это типичный способ построения API-интерфейсов, не подвергая внутренности типа (которые являются деталями реализации).

typedef struct _cl_context* cl_context; 

Делать это позволяет определить API, используя тип cl_context, без определения структуры _cl_context где-нибудь в заголовочных файлах. Ясно, что функции принимают этот тип (указатель) в качестве аргумента, но пользователь не обременен деталями struct _cl_context. Структуру можно определить в другом месте (в .c файле или в закрытом заголовке).

Другой подход вы упомянуть:

typedef void* cl_context; 

Это используется, а также во многих местах. Но требует машинного кодирования в коде повсюду, прежде чем аргумент может быть истолкован. И это не типично.Пользователь может передать любой указатель в качестве аргумента, и компилятор примет его - что не очень хорошо. используя реальный тип, обеспечивает некоторая безопасность с точки зрения аргументов, передаваемых взад и вперед.

+0

Спасибо, я не рассматривал случай, когда пользователь может попытаться передать мусор и принять его как пустоту *. – jklontz

2

В C, когда вы объявляете структура, как:

struct foo { };

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

struct foo f;

Поэтому C программисты склонны объявить как структуры:

typedef struct foo { } foo;

Как и в, foo является ЬурейеЕ для struct foo

Это требование пошел на C++.

Я не думаю, что typedef struct cl_context; компилируется. Может быть, вы имели в виду typedef struct _cl_context cl_context;?

Это просто так, что вызовы API могут принимать cl_context вместо cl_context *?

Это typedef позаботится об этом и устраняет необходимость добавления объявлений типа с помощью struct.

Вы, конечно же, не захотите использовать typedef void *cl_context;, потому что тогда вы потеряете безопасность типа.

+0

Спасибо, вы правы в том, что я хотел сказать «typedef struct _cl_context cl_context;» а не «typedef struct cl_context;». Я исправил это в своем вопросе. Это отличный ответ, я не рассматривал исключение ключевого слова «struct»! Хотел бы я согласиться с тем и другим. – jklontz