__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
不同,几乎没有任何理由重复调用具有相同参数的幂等函数。
我有一个函数,它接受两个数组并将 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
不同,几乎没有任何理由重复调用具有相同参数的幂等函数。