__attribute__((pure)) 应用于 void 函数

__attribute__((pure)) applied to void function

我有一个函数,它接受两个数组并将 pure 函数的结果写入第三个数组 (c_i = a_i / b_i):

inline
void    array_division      (ptrdiff_t nmemb,
                             double dest[static nmemb],
                             const double src1[static nmemb],
                             const double src2[static nmemb])
        __attribute__((nonnull, pure));

inline
void    array_division      (ptrdiff_t nmemb,
                             double dest[static nmemb],
                             const double src1[static nmemb],
                             const double src2[static nmemb])
{

        for (ptrdiff_t i = 0; i < nmemb; i++)
                dest[i] = src1[i] / src2[i];
}

GCC 抛出错误,因为它不期望 return void.

的纯函数

A pure function 是作为其参数的函数,以及这些参数指向的值;如果参数的 none 或它们指向的值在两次调用之间发生变化,则它们应该是多余的并且可以省略调用,评估为与前一次调用相同的值 returned .

我的函数遵循所有这些规则:如果 3 个数组中的 none 在两次函数调用之间发生变化,则可以完全删除该函数调用;并且它们的计算结果相同(即 none,因为它是 void)。

我认为 GCC 应该允许 __attibute__((pure)) 的这种用法是否正确?

我应该 return 一个假人 return 0; 以避免 GCC 抱怨吗?

编辑:

GCC 中的 BUG 状态:__ attribute __((pure)) to function with non-const pointers

至于为什么 return 0; 有效... 根据 https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute :

Because a pure function cannot have any observable side effects it does not make sense for such a function to return void. Declaring such a function is diagnosed.

但还要注意你不能 return void 的原因:它 没有意义 。您将放弃 return 值的能力,以及纯函数的唯一合法目的。

The pure attribute prohibits a function from modifying the state of the program that is observable by means other than inspecting the function’s return value.

这意味着,例如,禁止标记为 pure 的函数在您传入的数组中设置条目。我有点惊讶它允许 non-const 指针,通过他们分配的更少。

至于一旦你欺骗 GCC 允许修改这样的函数会发生什么,我不确定。这取决于 GCC 在这种情况下指定的内容。

您的函数不遵循纯函数的规则。 linked-to 文本非常清楚,多次 说不允许通过传递给函数的指针更改程序的可观察状态。从纯函数中唯一可以观察到的是它的 return 值。 通过 non-const 指针修改内存不是 return 值,而是副作用。

你的函数并不纯粹,因为它有副作用。如果优化器认为纯函数的 return 值未被使用,则根本不需要 调用它 ,即使是第一次。

因此,void 函数并不是纯粹有用的,因为它是一个 必须 可优化为 void nop() { } 的函数。没有任何意义。

此处唯一的编译器和文档错误是编译器在您添加 doubly-wrong return 0 时抑制了诊断。


您发现了另一组可以具有优化属性的函数 - 幂等。然而,问题在于只能省略重复调用 - 但与在循环条件中使用 strlen 不同,几乎没有任何理由重复调用具有相同参数的幂等函数。