9

C ++ 11中的一个可以以某种方式gcc将函数(不是类方法)标记为const告诉它是的并且不使用全局内存而只使用它的参数吗?

我试过了gcc__attribute__((const))正是我想要的。但是在函数中触及全局内存时不会产生任何编译时错误。

编辑 1

请小心。我的意思是纯函数。不是常数函数。GCC 的属性有点混乱。纯函数只使用它们的参数。

4

3 回答 3

7

你在找constexpr吗?这告诉编译器可以在编译时评估该函数。函数必须具有constexpr字面返回和参数类型,并且主体只能包含静态断言、类型定义、使用声明和指令以及一个返回语句。可以constexpr在常量表达式中调用函数。

constexpr int add(int a, int b) { return a + b; }

int x[add(3, 6)];

看过 的含义后__atribute__((const)),答案是否定的,你不能用标准 C++ 做到这一点。使用constexpr将达到相同的效果,但仅限于更有限的一组功能。但是,只要编译后的程序以相同的方式运行(as-if 规则),就没有什么可以阻止编译器自行进行这些优化。

于 2012-12-02T23:01:17.480 回答
3

因为这里已经提到了很多,所以让我们暂时忘掉元编程,它无论如何都是纯函数式的,而且离题了。但是,可以使用非 constexpr 参数调用constexpr 函数foo ,在这种情况下, foo实际上是在运行时评估的纯函数(我在这里忽略了全局变量)。但是您可以编写许多无法使用 constexpr 的纯函数,例如,这包括任何抛出异常的函数。

其次,我假设 OP 意味着将 pure 标记为供编译器检查的断言。GCC 的pure属性则相反,是 coder 帮助编译器的一种方式。

虽然 OP 问题的答案是否定的,但阅读尝试引入 pure 关键字(或不纯并让pure成为默认值)的历史非常有趣。

d-lang 社区很快发现“纯”的含义并不清楚。日志记录不应使函数不纯。在纯函数中应该允许不逃避函数调用的可变变量。具有不同地址的相同返回值不应被视为不纯。但 D 比扩展纯度更进一步。

所以d-lang社区引入了“弱纯”和“强纯”这两个词。但后来的争论表明,弱与强不是非黑即白,有灰色地带。见D 中的纯度

Rust 很早就引入了“纯”关键字;他们因为它的复杂性而放弃了它。在 Rust 中查看纯度

在“纯”关键字的巨大好处中,有一个丑陋的后果。一个模板化的函数可以是纯的也可以不是纯的,这取决于它的类型参数。这可能会增加模板实例化的数量。这些实例化可能只需要暂时存在于编译器中,而不需要进入可执行文件,但它们仍然可以延长编译时间。

在不修改语言的情况下,语法高亮编辑器可能会有所帮助。优化 C++ 编译器确实会考虑函数的纯粹性,它们只是不能保证捕获所有情况。

我很遗憾这个功能的优先级似乎很低。它使对代码的推理变得更加容易。我什至会争辩说,它会通过激励程序员以不同的方式思考来改进软件设计。

于 2018-03-18T15:07:13.050 回答
2

仅使用标准 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)。


之前有一个关于pureconstexpr. 主要是,每个constexpr函数都是pure,但反之则不然。

于 2012-12-02T23:00:44.950 回答