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

时间:2015-06-24 21:12:33

标签: c gcc warnings implicit-conversion complex-numbers

我正在使用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,或者在非复杂值上调用crealfcimagf,但是这个即使使用-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开关可以提供有关此行为的警告?它已经咬了我们,为这个项目切换工具链(铿锵)目前还不可行。

1 个答案:

答案 0 :(得分:3)

C11最终草案(N1570),6.3.1.7第2段:

  

当复数类型的值转换为实数类型时,将丢弃复数值的虚部,并根据相应实数类型的转换规则转换实部的值。

真实类型是整数和实数浮动类型。

C99理由解释了这背后的动机:

  

在数学中,当复数转换为实数时,虚部将被丢弃。 C99遵循相同的惯例。

并且(编号与C11相同):

  

§6.3.1.6和§6.3.1.7中的规范与Fortran的匹配。