C ++ 11中的一个可以以某种方式gcc
将函数(不是类方法)标记为const
告诉它是纯的并且不使用全局内存而只使用它的参数吗?
我试过了gcc
,__attribute__((const))
这正是我想要的。但是在函数中触及全局内存时不会产生任何编译时错误。
编辑 1
请小心。我的意思是纯函数。不是常数函数。GCC 的属性有点混乱。纯函数只使用它们的参数。
你在找constexpr
吗?这告诉编译器可以在编译时评估该函数。函数必须具有constexpr
字面返回和参数类型,并且主体只能包含静态断言、类型定义、使用声明和指令以及一个返回语句。可以constexpr
在常量表达式中调用函数。
constexpr int add(int a, int b) { return a + b; }
int x[add(3, 6)];
看过 的含义后__atribute__((const))
,答案是否定的,你不能用标准 C++ 做到这一点。使用constexpr
将达到相同的效果,但仅限于更有限的一组功能。但是,只要编译后的程序以相同的方式运行(as-if 规则),就没有什么可以阻止编译器自行进行这些优化。
因为这里已经提到了很多,所以让我们暂时忘掉元编程,它无论如何都是纯函数式的,而且离题了。但是,可以使用非 constexpr 参数调用constexpr 函数foo ,在这种情况下, foo实际上是在运行时评估的纯函数(我在这里忽略了全局变量)。但是您可以编写许多无法使用 constexpr 的纯函数,例如,这包括任何抛出异常的函数。
其次,我假设 OP 意味着将 pure 标记为供编译器检查的断言。GCC 的pure属性则相反,是 coder 帮助编译器的一种方式。
虽然 OP 问题的答案是否定的,但阅读尝试引入 pure 关键字(或不纯并让pure成为默认值)的历史非常有趣。
d-lang 社区很快发现“纯”的含义并不清楚。日志记录不应使函数不纯。在纯函数中应该允许不逃避函数调用的可变变量。具有不同地址的相同返回值不应被视为不纯。但 D 比扩展纯度更进一步。
所以d-lang社区引入了“弱纯”和“强纯”这两个词。但后来的争论表明,弱与强不是非黑即白,有灰色地带。见D 中的纯度
Rust 很早就引入了“纯”关键字;他们因为它的复杂性而放弃了它。在 Rust 中查看纯度。
在“纯”关键字的巨大好处中,有一个丑陋的后果。一个模板化的函数可以是纯的也可以不是纯的,这取决于它的类型参数。这可能会增加模板实例化的数量。这些实例化可能只需要暂时存在于编译器中,而不需要进入可执行文件,但它们仍然可以延长编译时间。
在不修改语言的情况下,语法高亮编辑器可能会有所帮助。优化 C++ 编译器确实会考虑函数的纯粹性,它们只是不能保证捕获所有情况。
我很遗憾这个功能的优先级似乎很低。它使对代码的推理变得更加容易。我什至会争辩说,它会通过激励程序员以不同的方式思考来改进软件设计。
仅使用标准 C++11:
namespace g{ int x; }
constexpr int foo()
{
//return g::x = 42; Nah, not constant
return 42; // OK
}
int main()
{}
这是另一个例子:
constexpr int foo( int blah = 0 )
{
return blah + 42; // OK
}
int main( int argc, char** )
{
int bah[foo(2)]; // Very constant.
int const troll = foo( argc ); // Very non-constant.
}
GCC 的含义__attribute__( const )
在GNU 编译器文档中记录为……
许多函数除了参数之外不检查任何值,并且除了返回值之外没有任何效果。基本上这只是比
pure
下面的属性更严格的类,因为函数不允许读取全局内存。
人们可能会认为这意味着函数结果应该只取决于参数,并且函数应该没有副作用。
这允许比 C++11 更通用的函数类constexpr
,它生成函数inline
,将参数和函数结果限制为文字类型,并将函数体的“活动”语句限制为单个return
语句,其中 (C++11 §7.1.5/3)
— 用于初始化返回值(6.6.3、8.5)的每个构造函数调用和隐式转换都应是常量表达式(5.19)中允许的那些之一
constexpr
sin
举个例子,制作一个函数很困难(我认为不是不可能,但很困难) 。
但结果的纯度只对两方很重要:
当已知为纯时,编译器可以省略具有已知结果的调用。
这主要是对宏生成代码的优化。用函数替换宏inline
以避免愚蠢地生成相同的子表达式。
当已知是纯的时,程序员可以完全删除调用。
这只是一个适当的文档问题。:-)
因此,与其寻找一种方法来sin
用语言表达 eg 的纯度,我建议避免通过宏生成代码,并记录纯函数本身。
并constexpr
用于实际上可能的功能(不幸的是,截至 2012 年 12 月,最新的 Visual C++ 编译器尚不支持constexpr
)。
之前有一个关于pure和constexpr
. 主要是,每个constexpr
函数都是pure,但反之则不然。