-O1/2/3 with -std=c++1y/11/98 - If <cmath> is included i'm getting error: '_hypot' was not declared in this scope

-O1/2/3 with -std=c++1y/11/98 - If <cmath> is included i'm getting error: '_hypot' was not declared in this scope

我刚刚使用 mingw-get-setup 更新了 MinGW,但如果我使用大于 -O0 的任何内容,我将无法构建包含 <cmath> header 的任何内容 -std=c++1y。 (我也尝试了 c++11c++98)我遇到了这样的错误:

g++.exe -pedantic-errors -pedantic -Wextra -Wall -std=c++1y -O3  -c Z:\Projects\C++\L6\src\events.cpp -o obj\src\events.o
In file included from z:\lander\mingw\lib\gcc\mingw32.8.1\include\c++\cmath:44:0,
                 from Z:\Projects\C++\L6\src\utils.h:4,
                 from Z:\Projects\C++\L6\src\events.cpp:10:
z:\lander\mingw\include\math.h: In function 'float hypotf(float, float)':
z:\lander\mingw\include\math.h:635:30: error: '_hypot' was not declared in this scope
 { return (float)(_hypot (x, y)); }

我这边有什么问题吗?
或者 mingw repo 的版本有问题?如果是这样,这个 header 有什么快速修复方法吗?

MinGW 使用 gcc 和 Microsoft 运行时库。微软的实现支持C90,但是对后来版本的C标准(C99和C11)的支持很差

C99 添加了 hypot 函数(连同 hypotfhypotl)。

如果您在调用 hypot 的程序中遇到此错误,例如:

#include <cmath>
int main() {
    std::cout << std::hypot(3.0, 4.0)) << '\n';
}

那么这只是 Microsoft 运行时库的限制,因此也是 MinGW 的限制。如果 任何 具有 #include <cmath> 的程序出现,则它是 MinGW 中的错误,可能是配置错误。

为了避免任何进一步的猜测和彻头彻尾的错误建议,例如使用 #if 0,让我从 MinGW 项目贡献者的角度给出一个权威的答案。

是的,include/math.h 的 MinGW.org 实现在 hypotf (float, float) 的内联实现中确实有一个错误;编译 C++ 时会触发错误,其中包含受影响的 header(就像包含 cmath 时一样), 导致 [=14 的任何编译器选项=] 被指定,(就像 OP 指出的那些 -std=c... 选项一样)。适当的解决方案是 而不是 来遮挡 math.h 文件的一部分,使用 #if 0 或其他方式,而是纠正 hypotf (float, float) 的损坏的内联实现;只需从对 _hypot (float, float) 的内联引用中删除虚假的前导下划线,其中其 return 值被转换为浮点 return 类型就足够了。

或者,在编译器选项中用等效的 -std=gnu... 替换 -std=c... 应该可以避免该错误,并且可能提供合适的解决方法。

FWIW,我对 MinGW.org 目前对 hypotl (long double, long double) 的实施也不完全满意;纠正这两个问题在我的下一个 MinGW 运行时版本的任务清单上,但是 ATM,我没有时间专门准备这个。

更新

此错误不再存在于 MinGW.org 运行时库的当前版本中(当前为 mingwrt-3.22.4,但自版本 3.22 起已修复)。如果您使用的是比这更早的版本,(包括 严重损坏 4.x 版本的 任何,您应该升级。

正如 Keith 所指出的,这是 MinGW.org header 中的错误。

作为编辑 MinGW.org header 的替代方法,您可以使用 MinGW-w64,它提供 MinGW.org 提供的一切,甚至更多。 有关运行时之间差异的列表,请参阅 this wiki page