GCC"__attribute__((纯))"关于"input state"吸气剂方法的建议 - 正确吗?
GCC `__attribute__ ((pure))` suggestion on "input state" getter method - correct?
使用 -Wsuggest-attribute=pure
编译使 GCC 建议可以使用 __attribute__ ((pure))
标记的潜在函数以进行优化。
以下是 GCC 文档中pure
的定义:
我许多函数除了返回值之外没有任何影响,它们的返回值仅取决于参数和/或全局变量。这样的函数可以像算术运算符一样进行公共子表达式消除和循环优化。这些函数应使用属性 pure 声明。
正在创建一个小型游戏引擎,其中我有一个包含input_state
成员的input_context
类。input_context
类通过从操作系统获取全局输入状态来更新每帧input_state
成员。
它还包含几个用于查询输入状态的"getter"。
简化示例:
class input_context
{
private:
input_state _input_state;
public:
void update()
{
os::fill_input_state(_input_state);
}
auto mouse_x() const noexcept
{
return _input_state._mouse_x;
}
auto mouse_y() const noexcept
{
return _input_state._mouse_y;
}
auto is_key_down(keycode k) const noexcept
{
// `_keys` is an array of `bool` values.
return _input_state._keys[k];
}
};
GCC告诉我,所有这些"getter方法",如mouse_x()
,mouse_y()
和is_key_down()
,都是__attribute__ ((pure))
的候选者。
我应该将这些方法标记为pure
吗?
我不这么认为,但GCC的建议让我对此感到疑惑。
我不确定如何解释 GCC 对pure
的定义 - 它说仅依赖参数和/或全局变量的函数应该被标记为这样。
在某种程度上,全局操作系统输入状态可以解释为全局变量。
另一方面,"getter 方法"总是返回不同的值,具体取决于
_input_state
成员变量。
标记为纯是可以的。以简化的形式考虑您的示例,并添加了一些 IO 函数:
#include <stdio.h>
class X {
int x_=0;
public:
int x() const noexcept __attribute__ ((pure)) /*__attribute__((noinline))*/;
void inc() noxcept { x_++; }
};
int X::x() const noexcept { puts("getting x"); return x_;}
int main(){
X x;
printf("%dn", x.x() + x.x() + x.x());
x.inc();
printf("%dn", x.x() + x.x() + x.x());
}
Pure允许您获得:
getting x
0
getting x
3
而不是
getting x
getting x
getting x
0
getting x
getting x
getting x
3
在优化级别至少为 -O1(在更高级别,您可能需要添加__attribute__((noinline))
以防止内联(。
如果状态在对这些 getter 的两次连续调用之间发生变化,只要编译器可以检测到状态已更改,就可以了。如果您需要运行non-const
方法来更改状态,则不违反纯度。但是,如果状态以编译器无法知道更改的方式on its own
更改(系统更改它/另一个线程更改它/信号处理程序更改它(,则 pure
属性不再是合法的。
您可以将这些方法标记为纯方法,因为它们没有副作用。
根据您引用的文档,纯函数可以依赖于全局变量/外部状态。我想这也与关闭的概念有关。您可以根据外部变量定义函数f
(例如使用 Haskell(:
x=1
f y = x + y
函数本身仍然没有副作用(尽管在 Haskell 中,你不能更改 x
的值,而你可以在 C/C++ 中更改函数/方法之外的x
(。
pure
和 const
之间的区别总结在这个问题中: GNU C 中的 __attribute__((const(( 与 __attribute__((pure((
引用那里的答案:
attribute((const(( 与 attribute((pure(( 相同,但无法访问全局变量。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 处理编译器关于可能丢失数据的警告的最优雅方法是什么
- 关于异常,覆盖标准异常方法
- 尝试使用 Qt 库中的 QPixmap 将图像拆分为多个块。关于他的复制方法的工作方式,我有什么不明白的吗?
- Scott Meyers关于首选非成员非友元方法的建议是否适用于对象构造?
- 关于链表,这两种方法有什么不同?C++中的1个自变量与2个自变量
- C++ 关于对方法的引用
- 关于 direct3d 关于 D3DXCreateTextureFromFileEx 的方法
- 有没有一种方法可以获得关于助推的信息::蝇量级内部容器
- 关于在强制转换为子类的超类时调用其重写方法
- 没有关于方法或属性的直接提示
- GCC"__attribute__((纯))"关于"input state"吸气剂方法的建议 - 正确吗?
- 关于机器学习/计算机视觉领域实用方法的问题
- 关于通过Get和Set方法传递字符串
- 关于通过Get和Set方法传递字符串
- 关于CCSprite中的create方法
- 关于我课上const方法的几个问题
- 关于指针对齐,有没有一种方法可以使指针与给定的内存边界对齐
- 关于实现字典数据结构的正确方法的一般问题
- c++.h和.cpp文件-关于方法