繁体   English   中英

在C99中为复杂算术输入安全性

[英]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或者调用crealfcimagf上的非复数值,但是这-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM