【问题标题】:Identifying function parameters as Input or Output将函数参数识别为输入或输出
【发布时间】:2015-12-13 14:49:44
【问题描述】:

所以我有一个简单的功能以及一些文档:

/**
 *  @param[out] dest is overwritten by the second argument
 *  @param[in] src is value to overwrite the first argument with
 */
void Copy(int &dest, int src) { dest = src; }

可能不是很有用,但很明显dest 是输出。但是,由于使用指针,这条线对我来说变得模糊:

void Copy(int *dest, int src) { *dest = src; }

dest 应该仍然是输出吗?指针的值不会被修改,只有它指向的内存中的值会被修改。但我仍然会说可能是的。继续:

void Write(FILE *fw, int src) { fwrite(&src, sizeof(src), 1, fw); }

现在这对我来说真的很可疑,我会将fw 标记为输入,尽管它在逻辑上是一个输出,而且FILE 结构的内容将在此过程中被修改(但那个非常不透明给我)。

另一方面:

void Open(FILE &*fw, const char *filename) { fw = fopen(filename, "w"); }

显然是输出。 FILE句柄被函数初始化,指针的值被覆盖。

将参数标记为输出是否有良好的经验法则或推理?

我什至不想像 C++ 那样进入[in,out] 参数,这些基本上都是[out] 参数(例如,如果通过std::vector 传递输出,函数需要获取一个实例作为输入并且输出甚至可以重用存储)。

【问题讨论】:

    标签: c++ doxygen


    【解决方案1】:

    Opinions vary 关于是否应该使用输出参数,更不用说应该如何记录它们了。不过,它们是常用的,您的问题是有效的。

    参数是否应标记为[in][out][in,out] 取决于参数的用途。

    通常,输出参数的目的是允许被调用函数在单个返回值不足时将附加信息传递给调用函数。此“附加信息”通过调用函数提供的参考参数传递。可以使用 C++ 引用运算符 (&) 或通过指针提供引用参数,这是一种略有不同的车辆,但具有相同的结果。

    所以如果参数的目的是允许被调用函数向调用函数提供信息,那么它应该在文档中被标识为输出

    如果通过参数向函数提供文件句柄或文件名,则将被视为 输入 参数,即使该函数旨在写入文件。这是因为

    • 函数未通过参数将信息传递回调用例程
    • 写入文件被视为函数的side-effect

    如果引用参数用于双向传递信息,则应将其记录为[in,out]

    此外

    在记录函数时,将函数视为提供给调用者的服务。您的文档的受众是编写将调用您的函数的代码的程序员。编写文档,就好像您(函数的编写者)不知道调用代码的上下文或细节一样。文档的目的是概括描述该函数的作用,以及详细说明如何使用该函数。

    因此,如果函数的设计者打算将dest 用作输出,则应将其标记为输出。您还应该考虑调用者对通过该输出提供的数据不感兴趣的情况。通常这是由调用者提供一个空指针作为该参数的参数来指示的。在将任何数据写入*dest 之前,您的函数应该测试以确保dest 不为空。参数dest 的文档应说明如果dest 是空指针,则不会写入任何数据。

    输入指针参数使用 const

    顺便说一句,如果指针参数仅用于输入,则应使用 const 关键字修改该参数,如下所示:

    void Copy(int *dest, const int *src) { *dest = *src; }
    

    这有以下好处:

    • 如果Copy 函数的程序员错误地尝试这样做,它将阻止Copy 函数写入*src 位置
    • 它通知并保证编写调用Copy的代码的程序员,他的src缓冲区不会被Copy修改
    • 它是自记录的,如果您在使用const 时保持一致:标记为const 的指针参数显然是仅用于输入的,而未标记为const 的指针参数可能用于输出.

    另请参阅

    【讨论】:

    • 所以你的意思是,在我的问题的第二个示例(带有指针的示例)中,dest 仅在调用函数读取值并且如果它没有读取值时被标记为输出它是一个输入参数?那是非常上下文敏感的,可能无法正确记录这样的功能。如果它是从多个地方调用的,有些只关心返回值(或只关心调用所用的时间)怎么办?
    • 不,我不是这个意思。我在回答中添加了“进一步”部分来解决这个问题。我还添加了关于使用 const 作为输入指针参数的部分。
    猜你喜欢
    • 2012-05-01
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 2010-10-13
    • 2014-12-31
    相关资源
    最近更新 更多