简体   繁体   中英

Type safety for complex arithmetic in C99

I'm using C's complex arithmetic support and ran into some surprising and undesirable behavior. 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. Clang 3.6.1 at least emits such a warning:

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? It has already bitten us, and switching toolchains (to clang) for this project isn't feasible at present time.

C11 final draft (N1570), 6.3.1.7 paragraph 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:

In mathematics, when a complex is converted to real, the imaginary part is discarded. C99 follows the same convention.

And (numbering is identical to C11):

The specification in §6.3.1.6 and §6.3.1.7 match Fortran's.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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