简体   繁体   English

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

[英]Type safety for complex arithmetic in C99

I'm using C's complex arithmetic support and ran into some surprising and undesirable behavior. 我正在使用C的复杂算术支持,并遇到了一些令人惊讶和不良行为。 Complex values seem to be implicitly convertible to real ones, discarding the imaginary part. 复数值似乎可以隐式转换为实数,丢弃虚部。

Consider the following: 考虑以下:

#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;
}

I would expect to receive some warning that I am assigning a float complex to a float or perhaps calling crealf and cimagf on a non-complex value, but this builds cleanly on GCC 5.1, even with -Wall -Wextra -Wconversion switches. 我希望收到一些警告,我将float complex crealf float或者调用crealfcimagf上的非复数值,但是这-Wall -Wextra -Wconversion地构建在GCC 5.1上,即使使用-Wall -Wextra -Wconversion开关-Wall -Wextra -Wconversion Clang 3.6.1 at least emits such a warning: 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);
                                       ~   ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~

Why can complex values "collapse" to real ones? 为什么复杂的价值观会“崩溃”到真正的价值观? Is there some verbiage about this in the standard? 在标准中是否有一些关于此的措辞? And is there some additional switch for GCC that can provide warnings about this behavior? 是否有一些额外的GCC开关可以提供有关此行为的警告? It has already bitten us, and switching toolchains (to clang) for this project isn't feasible at present time. 它已经咬了我们,并且为这个项目切换工具链(到clang)目前是不可行的。

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

When a value of complex type is converted to a real type, the imaginary part of the complex value is discarded and the value of the real part is converted according to the conversion rules for the corresponding real type. 当复数类型的值转换为实数类型时,将丢弃复数值的虚部,并根据相应实数类型的转换规则转换实部的值。

Real types are integer and real floating types. 实数类型是整数和实数浮点类型。

The C99 rationale explains the motivation behind this: C99理由解释了这背后的动机:

In mathematics, when a complex is converted to real, the imaginary part is discarded. 在数学中,当复数转换为实数时,虚部被丢弃。 C99 follows the same convention. C99遵循相同的惯例。

And (numbering is identical to C11): 并且(编号与C11相同):

The specification in §6.3.1.6 and §6.3.1.7 match Fortran's. §6.3.1.6和§6.3.1.7中的规范与Fortran相匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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