C / C ++ функция / метод оформления - PullRequest
5 голосов
/ 29 октября 2009

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не делал C ++ в течение некоторого времени ...

Распространено ли в наши дни оформление объявлений функций / методов C / C ++ для улучшения читабельности?

Сырой пример:

void some_function(IN int param1, OUT char **param2);

с макросами IN и OUT , определенными с пустым телом (т.е. облегченной документацией, если вы будете в этом примере). Конечно, я понимаю, что это идет параллельно с «блоком комментариев документа», связанным с методом / функцией.

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

Ответы [ 10 ]

17 голосов
/ 29 октября 2009

Мне бы не понравилось такое украшение.

Намного лучше использовать const, ссылки и константы, как в

void some_function(AClass const &param1, AnotherClass &param2)

Обычно int передаются по значению, а не по ссылке, поэтому я использовал AClass и AnotherClass для примера. Мне кажется, что добавление empy IN и OUT будет отвлекать.

7 голосов
/ 29 октября 2009

Заголовки Windows на самом деле делают именно это. См. Аннотации заголовка для получения полного списка использованных аннотаций. Например "

DWORD
WINAPI
GetModuleFileName(
    __in_opt HMODULE hModule,
    __out_ecount_part(nSize, return + 1) LPTSTR lpFilename,
    __in DWORD nSize
    );

Для этой функции hModule является необязательным входным параметром, lpFilename является выходным параметром, который хранит максимум nSize символьных элементов и который будет содержать (возвращаемое значение функции) +1 символьных элемента в по возвращении, а nSize - входной параметр.

5 голосов
/ 29 октября 2009

Для документирования достаточно хорошо написанного блока комментариев, поэтому он не служит какой-либо цели. Кроме того, некоторые синтаксические анализаторы комментариев к документации имеют специальный синтаксис именно для такой вещи; например, учитывая Doxygen, вы могли бы написать:

/**
 * @param[in]  param1 ...
 * @param[out] param2 ...
 **/
void some_function(int param1, char **param2);
4 голосов
/ 29 октября 2009

Я думаю, что это плохая идея. Тем более, что любой может прийти и определить макросы IN / OUT и оставить вас в куче больших неприятностей.

Если вы действительно хотите задокументировать, добавьте туда комментарии.

void some_function(/* IN */ int param1, /* OUT */ char **param2);

Также зачем использовать out, если возвращаемое значение будет работать нормально.
Также я бы предпочел использовать pass by ref и const ref, чтобы указать мои намерения. Кроме того, компилятор теперь выполняет относительно хорошие операции по предупреждению намерений, когда ваш код верен.

void some_function(/* IN */ int const& param1, /* OUT */ char*& param2);
// OK for int const& is kind of silly but other types may be usefull.
2 голосов
/ 29 октября 2009

Не на C ++, я не занимался программированием на C профессионально, но, по крайней мере, на C ++ тип параметров не требует пояснений:

void f( std::string const & ); // input parameter
void f( std::string );         // input parameter again (by value)
void f( std::string& );        // in/out parameter
std::string f();               // output

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

Об указателях. Мы склонны ограничивать использование необработанных указателей в наших интерфейсах методов. Когда это необходимо, их можно использовать, но в целом предпочтительнее использовать умные указатели. С другой стороны, семантика владения происходит от выбора умного указателя: shared_ptr <> для разветвленной совместной ответственности (или при необходимости), auto_ptr <> / unique_ptr <> для единоличного владения (обычно как возвращаемое значение от фабрик, локальных или атрибутов членов). ..

1 голос
/ 29 октября 2009

Единственное, что хуже, чем это было давно замечено в программе на C, написанной Pascal dev:


#define begin {
#define end   }

int main( int argc, char* argv[] )
begin
  ...
end
1 голос
/ 29 октября 2009

Я видел это, но не думаю, что скажу, что это "обычное дело".

Win32 API (C не C ++) использует нечто подобное:

WINADVAPI
BOOL
WINAPI
CreateProcessWithLogonW(
    __in        LPCWSTR lpUsername,
    __in_opt    LPCWSTR lpDomain,
    __in        LPCWSTR lpPassword,
    __in        DWORD dwLogonFlags,
    __in_opt    LPCWSTR lpApplicationName,
    __inout_opt LPWSTR lpCommandLine,
    __in        DWORD dwCreationFlags,
    __in_opt    LPVOID lpEnvironment,
    __in_opt    LPCWSTR lpCurrentDirectory,
    __in        LPSTARTUPINFOW lpStartupInfo,
    __out       LPPROCESS_INFORMATION lpProcessInformation
      );

В случае компиляторов Visual C ++ 2005 и более поздних версий они фактически отображаются на объявления типа __$allowed_on_parameter и проверяются во время компиляции.

1 голос
/ 29 октября 2009

Я пытаюсь использовать:

  • Значения для входных параметров или ссылок, если они большие
  • Ссылки на параметры
  • Указатели для передачи права на вызываемую функцию

Большую часть времени действительно легко увидеть, какие параметры IN или OUT, собственно имена в объявлении - хорошая документация.

Я нахожу эти IN, OUT аддоны раздражающими.

0 голосов
/ 30 октября 2009

Я видел использование префиксов i_, o_, io_ в дополнение к информации в типах параметров:

void some_function(int i_param1, char** o_param2, int& io_param3);
0 голосов
/ 29 октября 2009

Я не видел этого раньше. Я думаю, что было бы лучше поместить такую ​​информацию в комментарии.

...