我正在使用C&C的复杂算术支持,并遇到了一些令人惊讶和不良行为。复数值似乎可以隐式转换为实数,丢弃虚部。
请考虑以下事项:
#include <complex.h>
#include <stdio.h>
float complex getComplex(float real, float imag)
{
return real + imag * I;
}
int main()
{
const float /* missing complex! */ c = getComplex(25, 6) / getComplex(2, 4);
printf("%f + %f J\n", crealf(c), cimag(c));
return 0;
}
我希望收到一些警告,表示我正在为float complex
分配float
,或者在非复杂值上调用crealf
和cimagf
,但是这个即使使用-Wall -Wextra -Wconversion
开关,也可以在GCC 5.1上完全构建。 Clang 3.6.1至少发出这样的警告:
wut.c:11:62: warning: implicit conversion discards imaginary component: '_Complex float' to 'float'
[-Wconversion]
const float /* missing complex! */ c = getComplex(25, 6) / getComplex(2, 4);
~ ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
为什么复杂的价值观会崩溃&#34;对真实的?在标准中是否有一些关于此的措辞?是否有一些额外的GCC开关可以提供有关此行为的警告?它已经咬了我们,为这个项目切换工具链(铿锵)目前还不可行。
答案 0 :(得分:3)
C11最终草案(N1570),6.3.1.7第2段:
当复数类型的值转换为实数类型时,将丢弃复数值的虚部,并根据相应实数类型的转换规则转换实部的值。
真实类型是整数和实数浮动类型。
C99理由解释了这背后的动机:
在数学中,当复数转换为实数时,虚部将被丢弃。 C99遵循相同的惯例。
并且(编号与C11相同):
§6.3.1.6和§6.3.1.7中的规范与Fortran的匹配。