c - C99 中复杂算术的类型安全

标签 c gcc warnings implicit-conversion complex-numbers

我在使用 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 在一个非复杂的值上,但这完全建立在 GCC 5.1 上,即使使用 -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 段:

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.

实型是整型和浮点型。

C99 基本原理解释了这背后的动机:

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

并且(编号与 C11 相同):

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

关于c - C99 中复杂算术的类型安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31037149/

相关文章:

c - 在ubuntu 12.04中使用C发送AT命令到teltonika GSM调制解调器

c - 输入 fget 时检测到堆栈崩溃

linux - 在 Linux 上构建 FBX SDK

c - gcc 报告 "will never be executed"关于行 : while(fgets(line, MAX_LINE, stdin) != NULL)

.net - 警告 : Variable is passed by reference before it has been assigned a value. 运行时可能会导致空引用异常

C取消引用指向不完整类型的指针

c - 仅在线程中发生冲突时才使用互斥锁

c - 未找到从头文件链接到的头文件。

c - 当您使用 GCC 编译 C 代码时,堆栈是否以错误的方式增长

java类型安全:not parameterized generic type effect on performance