GCC 中的表达式中间体(如果这就是它们的实际名称)
我正在尝试转换用 VS 编写的数学库,以便它可以通过 GCC 进行编译。问题是,我有很多重载的运算符,如下所示:
模板
<类型名称T>
内联四元数
运算符+(四元数
&a, 四元数
&b)
{返回四元数
(a.x+bx,a.y+by,a.z+bz,a.w+bw);}
等等。
问题是:这些运算符是在其他编译器支持为表达式创建的自动中间体的假设下设计的,如下所示:
...
四元数
q = log(exp(q0)*t);
...
如果没有它们,上面的内容将需要变成:
...
四元数
tmp = exp(q0);
tmp *= t;
四元数
q = log(tmp);
...
这只是一个简单的例子。使用这个库的系统中的一些表达式将扩展到数百行——考虑到调试汇编风格的数字代码所涉及的开销,例如,一个超过 600 行的函数,这是一个天文数字,这是非常令人不快的。最少的。
在我看来,重载运算符的整个机制被引入语言中只是为了为普通函数提供不同的命名约定,而在数学表达式方面没有提供真正的语法优势,这似乎是不合理的。
但是,当然,我希望我的假设是错误的。
这让我想问:GCC 是否有能力创建自动中间体?如果没有,除了 MS 品牌之外,还有哪些编译器能够做到这一点?
或者我是否完全以错误的方式处理了这个问题,并且有更好的技术来创造相同的效果?
I am trying to convert a math library written with VS so it will compile though GCC. The trouble is, I have a lot of overloaded operators that look like this:
template<typename T>
inline quaternion<T>
operator+(quaternion<T>
&a, quaternion<T>
&b)
{return quaternion<T>
(a.x+b.x,a.y+b.y,a.z+b.z,a.w+b.w);}
and so on.
The problem is: These operators were designed under the assumption that other compilers would support the automatic intermediates created for expressions like the following:
...
quaternion<T>
q = log(exp(q0)*t);
...
Without them, the above would need to turn into:
...
quaternion<T>
tmp = exp(q0);
tmp *= t;
quaternion<T>
q = log(tmp);
...
And this is just a simple example. Some of the expressions within the systems that use this library would expand to several hundreds of lines -- something quite unpleasant considering that the overhead involved in debugging assembly-style numerics code for, say, a single function that stretches over 600 lines is astronomical in the least.
It seems unreasonable to me that the whole mechanism of overloading operators was introduced into the language only to provide a different naming convention for ordinary functions, while offering no real syntactical advantage when it comes to mathematical expressions.
But, of course, I hope I am wrong in assuming this.
Which brings me to ask: Does GCC have the ability to create automatic intermediates? If not, what compilers aside from the MS brands are capable of this?
Or have I gone about this in the wrong way altogether and there is a better technique for creating the same effect?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的非修改运算符需要通过 const 引用获取参数,例如,
标准 C++ 不允许您将未命名的临时对象(您的中间值)绑定到非常量引用。听起来 MSVC++ 可能允许将此作为扩展。
Your non-modifying operators need to take their arguments by const reference, e.g.
Standard C++ does not allow you to bind unnamed temporaries (which your intermediate values are) to non-const references. It sounds like MSVC++ might have permitted this as an extension.
您所显示的代码应该不需要需要为 gcc 或任何其他正常运行的 C++ 编译器重写。 C++ 要求编译器能够生成临时变量(您所说的中间体),包括您所展示的临时变量。虽然 gcc 接受的内容和 VC++ 接受的内容之间存在一些差异,但它们通常很小(通常 VC++ 接受理论上不应该接受的代码)。在上面的代码中,您确实是这样:您通过非常量引用传递参数,但临时变量只能通过值或常量引用传递。更改它,gcc 应该接受该代码。
如果您还有其他问题,我的建议是更直接地询问另一个问题,涉及您尝试移植到 gcc 的一些代码示例,并说明您在这样做时遇到的问题。
The code you've shown should not require rewriting for gcc or anything other properly functioning C++ compiler. C++ requires the compiler to be able to generate temporaries (what you're calling intermediates), including the ones you've shown. While there are some differences between what gcc will accept and what VC++ will accept, they're usually pretty minor (typically VC++ accepting code that it theoretically shouldn't). In the code above, you have exactly that: you're passing arguments by non-const reference, but temporaries are only supposed to be able to be passed by value, or const reference. Change that, and gcc should accept the code.
If you have other problems, my advice would be to ask another question more directly about some examples of code you're trying to port to gcc, and telling about what problems you're encountering in doing so.