gpt4 book ai didi

c++ - 标准库函数 abs() 在不同 C++ 编译器上的异常行为

转载 作者:太空宇宙 更新时间:2023-11-03 10:39:13 27 4
gpt4 key购买 nike

考虑以下程序:

#include <cstdio>
#include <cmath>

int main()
{
int d = (int)(abs(0.6) + 0.5);
printf("%d", d);
return 0;
}

g++ 7.2.0 输出 0(查看现场演示 here)

g++ 6.3.0(查看现场演示 here)

prog.cc: In function 'int main()':
prog.cc:6:26: error: 'abs' was not declared in this scope
int d = (int)(abs(0.6) + 0.5);
^
prog.cc:6:26: note: suggested alternative:
In file included from prog.cc:2:0:
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/cmath:103:5: note: 'std::abs'
abs(_Tp __x)
^~~

clang++ 5.0.0 输出 1(查看现场演示 here)

clang++ 3.6.0(查看现场演示 here)

prog.cc:6:19: error: use of undeclared identifier 'abs'; did you mean 'fabs'?
int d = (int)(abs(0.6) + 0.5);
^~~
fabs
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:181:14: note: 'fabs' declared here
__MATHCALLX (fabs,, (_Mdouble_ __x), (__const__));
^
/usr/include/math.h:71:26: note: expanded from macro '__MATHCALLX'
__MATHDECLX (_Mdouble_,function,suffix, args, attrib)
^
/usr/include/math.h:73:22: note: expanded from macro '__MATHDECLX'
__MATHDECL_1(type, function,suffix, args) __attribute__ (attrib); \
^
/usr/include/math.h:76:31: note: expanded from macro '__MATHDECL_1'
extern type __MATH_PRECNAME(function,suffix) args __THROW
^
/usr/include/math.h:79:42: note: expanded from macro '__MATH_PRECNAME'
#define __MATH_PRECNAME(name,r) __CONCAT(name,r)
^
/usr/include/x86_64-linux-gnu/sys/cdefs.h:88:23: note: expanded from macro '__CONCAT'
#define __CONCAT(x,y) x ## y
^
1 error generated.

Microsoft VC++ 19.00.23506 输出 1(查看现场演示 here)

这个程序到底发生了什么?为什么在不同的 C++ 编译器上编译时会给出不同的输出?为什么即使在同一编译器的不同版本上,程序也会表现出不同的行为?这是编译器问题还是标准库 (libstdc++ & libc++) 问题? C++ 标准对此有何规定?

P.S:我知道我需要编写 std::abs 而不是 abs。但这不是我的问题。

最佳答案

所有从 C 标准库引入功能的 cname 库头都必须在命名空间 std 中引入这些符号。它们也可以,但绝对不是必须将它们引入全局命名空间。 [headers]/4 :

Except as noted in Clauses [library] through [thread] and Annex [depr], the contents of each header cname is the same as that of the corresponding header name.h as specified in the C standard library. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope of the namespace std. It is unspecified whether these names (including any overloads added in Clauses [language.support] through [thread] and Annex [depr]) are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations.

所以不同的编译器,甚至不同的编译器版本,意味着不同的实现细节。

关于c++ - 标准库函数 abs() 在不同 C++ 编译器上的异常行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48089039/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com