考虑以下测试代码:
#include <tgmath.h>
void test()
{
double x=cos(4.5);
}将其编译为与
arm-none-eabi-gcc test.c -c在Ubuntu 18.04 (gcc 6.3.1,newlib 2.4.0)上运行良好,但在Ubuntu 20.04 (gcc 9.2.1,newlib 3.3.0)上,我得到以下错误:
In file included from test.c:1:
test.c: In function 'test':
test.c:5:14: error: 'ccosl' undeclared (first use in this function); did you mean 'ccosh'?
5 | double x=cos(4.5);
| ^~~
test.c:5:14: note: each undeclared identifier is reported only once for each function it appears in
test.c:5:14: error: argument 6 of '__builtin_tgmath' is not a function pointer显然,cos的定义在某种程度上发生了变化,因此它现在提到了没有在任何地方声明的ccosl。
如果我从tgmath.h更改为math.h,该错误将不再出现。这当然只是一种变通方法,而不是修复方法,因为这样我就失去了float与double的类型泛型。
我的问题是:我如何让它正常工作?我是否必须添加一些编译选项,或者这只是工具链中的一个bug?
发布于 2020-08-28 20:58:14
工具链的不同版本之间的区别似乎在于不同版本的tgmath cos宏的GCC实现。也就是说,使用gcc的-E选项进行编译会生成6.3.1中double x=cos(4.5)的以下(已清理)扩展:
double x=__builtin_choose_expr(__builtin_classify_type(4.5) == 9,
__builtin_choose_expr(__builtin_types_compatible_p(__typeof__(__real__(4.5)), long double),
ccosl(4.5),
__builtin_choose_expr(__builtin_types_compatible_p(__typeof__(__real__(4.5)), double) || __builtin_classify_type(__real__(4.5)) == 1,
ccos(4.5),
ccosf(4.5))
),
__builtin_choose_expr(__builtin_types_compatible_p(__typeof__(4.5), long double),
cosl(4.5),
__builtin_choose_expr(__builtin_types_compatible_p(__typeof__(4.5), double) || __builtin_classify_type(4.5) == 1,
cos(4.5),
cosf(4.5))
)
);而在GCC 9.3.0中,扩展是作为一个简单的函数调用:
double x=__builtin_tgmath (cosf, cos, cosl, ccosf, ccos, ccosl, 4.5);两者之间的主要区别是__builtin_choose_expr不会计算未选择的表达式(如the docs中所说),而__builtin_tgmath是一个函数,它需要所有参数都有效。而且看起来newlib在它的complex.h中从来没有使用过ccosl,所以它似乎与新版的GCC不兼容。
https://stackoverflow.com/questions/63632989
复制相似问题