是否可以编写这些 pure_assert 和 const_assert 宏?
GCC __attribute__((pure))
和 __attribute__((const))
分别允许将函数声明为无副作用和引用透明;假设我想编写 pure_assert
和 const_assert
宏,其参数必须是适当严格级别的表达式,即:
assert(oops_a_side_effect());
默默地导致调试和发布中的不同行为,但是:
pure_assert(oops_a_side_effect());
const_assert(oops_read_a_global());
至少在调试版本中会出现编译时错误。由于我希望是显而易见的原因,您不能只创建一个声明 __attribute__((pure))
的 pure_assert_impl
并将宏扩展到它。那么这些宏可以写吗?
The GCC __attribute__((pure))
and __attribute__((const))
allow functions to be declared as non–side-effecting and referentially transparent, respectively; let's say I want to write pure_assert
and const_assert
macros, whose argument must be an expression of the appropriate level of strictness, that is:
assert(oops_a_side_effect());
Silently results in different behaviours in debug and release, but:
pure_assert(oops_a_side_effect());
const_assert(oops_read_a_global());
Would be a compile-time error, at least in debug builds. For what I should hope are obvious reasons, you can't just create a pure_assert_impl
declared __attribute__((pure))
and have the macro expand to it. So is it possible to write these macros?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
gcc 是否强制规定 pure 和 const 函数不能分别调用非纯函数或非常量函数?如果是这样,您可以定义一个正确属性的函数模板,它将函数指针作为模板参数,并让宏扩展为该函数模板的调用。我假设您需要支持带有参数的函数,这对于 C++0x 可变参数模板或 lambda 来说效果更好。
Does gcc enforce that pure and const functions cannot call non-pure or non-const functions, respectively? If so, you could define a properly attributed function template which takes a function pointer as a template parameter, and let the macro expand to an invocation of that function template. I assume you need to support functions that take parameters, this would work better with C++0x variadic templates or lambdas.
gcc 不以任何方式强制纯度或引用透明度。这些属性只是给优化器的提示。所以答案是否定的。
gcc does not enforce purity or referential transparency in any way. These attributes are just hints for the optimiser. So the answer is no.
我怀疑是否有一个真正好的解决方案,但我发现了类似
const_assert()
的可能性,它似乎可以工作我有两个版本的 gcc(4.1.2 和 4.4.4)。这实际上是在检查表达式
(x) == (x)
是否被编译器视为编译时常量,如果不是,则会造成损坏。 “好的”情况实际上变成了assert(x);
而坏的情况会生成编译时错误:但是,启用优化后,它仍然会在预期的情况下产生错误,但其中之一是有点奇怪:
...您会期望 __builtin_constant_p() 的结果根据定义被视为常量!所以我不确定我是否真的会相信真正的代码......
(而且我现在对
pure_assert()
没有任何好主意!)I doubt that there's a really good solution for this, but I've found a possibility for something like
const_assert()
, which appears to work with the two versions of gcc I have readily to hand (4.1.2 and 4.4.4).This is really checking whether the expression
(x) == (x)
is regarded as a compile-time constant by the compiler, and creating brokenness if it's not. The "good" cases effectively becomeassert(x);
and the bad ones generate compile-time errors:However, with optimisation enabled, it still produces errors in the expected cases, but one of them is a bit odd:
...you'd expect the result of
__builtin_constant_p()
to be regarded as a constant by definition! So I'm not sure that I would really trust this for real code...(And I don't have any good ideas right now for
pure_assert()
!)恐怕运气不好。即使在编译器开始查看代码之前,预处理器也会扩展宏。
解决方案可能是让断言测试表达式在无论发布或调试模式下都进行评估,但仅在调试模式下测试结果。
Tough luck, I'm afraid. Macros are expanded by the preprocessor, even before the compiler starts looking at the code.
What maybe could be a solution, is to let the assert test expression be evaluated regardless of release or debug mode, however let the result be tested only in debug mode.