[英]Type safety for complex arithmetic in C99
我正在使用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
crealf
float
或者调用crealf
和cimagf
上的非复数值,但是这-Wall -Wextra -Wconversion
地构建在GCC 5.1上,即使使用-Wall -Wextra -Wconversion
开关-Wall -Wextra -Wconversion
。 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);
~ ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
为什么复杂的价值观会“崩溃”到真正的价值观? 在标准中是否有一些关于此的措辞? 是否有一些额外的GCC开关可以提供有关此行为的警告? 它已经咬了我们,并且为这个项目切换工具链(到clang)目前是不可行的。
C11最终草案(N1570),6.3.1.7第2段:
当复数类型的值转换为实数类型时,将丢弃复数值的虚部,并根据相应实数类型的转换规则转换实部的值。
实数类型是整数和实数浮点类型。
C99理由解释了这背后的动机:
在数学中,当复数转换为实数时,虚部被丢弃。 C99遵循相同的惯例。
并且(编号与C11相同):
§6.3.1.6和§6.3.1.7中的规范与Fortran相匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.