C++ 优化者会根据编译时常数推导数学表达式吗?

C++ 优化者会根据编译时常数推导数学表达式吗?,c++,gcc,compiler-optimization,C++,Gcc,Compiler Optimization,如果我有一些依赖于输入的数学方程,这些输入可以是零或非零(模板参数,在编译时已知),那么优化程序会对方程进行求值,并优化出它知道将求值为0或1的表达式 例如: double x = y * Eval<type>::value; 如果Eval::value为0,x将始终为1 优化人员是否可以解决此问题,并将x替换为0或1代码中的其他位置,或者这些计算是否会在运行时执行 我将gcc 4.7与-O3一起使用编辑:我错了,编译器在使用浮点数时按预期工作。 只要表达式是整数相关的,那么-03

如果我有一些依赖于输入的数学方程,这些输入可以是零或非零(模板参数,在编译时已知),那么优化程序会对方程进行求值,并优化出它知道将求值为0或1的表达式

例如:

double x = y * Eval<type>::value;
如果
Eval::value
0
x
将始终为
1

优化人员是否可以解决此问题,并将
x
替换为
0
1
代码中的其他位置,或者这些计算是否会在运行时执行


我将gcc 4.7与
-O3
一起使用编辑:我错了,编译器在使用浮点数时按预期工作。

只要表达式是整数相关的,那么
-03
中的gcc 4.6.3显然可以做到这一点

示例代码:

#include <cstdio>
inline int x(double y)
{
   if (y == 0)
      printf("Hello bob3\n");
   else
      printf("Why do I bother\n");

};

const int c = 0;

int main()
{
   int f;
   scanf("%d",&f);

   x(f * c);
}

如果你熟悉汇编,你可以看看它的汇编输出。我打赌你甚至可以用足够的技巧在编译时强制它这样做(SFINAE和诸如此类)。对于这种形式的问题,唯一真正正确的答案是“允许,但不必”。在这种情况下,添加一个“编译器通常无法对浮点计算进行太多代数优化,除非使用“继续并以牺牲正确性为代价优化速度”开关。“你确定你的假设是正确的吗<如果
y
属于
double
类型,则code>y*0并不总是零。SFINAE工作非常完美,这正是我所写的,但后来我厌倦了。这只适用于第一个表达式,第二个表达式更复杂,需要模板材料
#include <cstdio>
inline int x(double y)
{
   if (y == 0)
      printf("Hello bob3\n");
   else
      printf("Why do I bother\n");

};

const int c = 0;

int main()
{
   int f;
   scanf("%d",&f);

   x(f * c);
}
    .file   "foo.cpp"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "%d"
.LC1:
    .string "Hello bob3"
    .section    .text.startup,"ax",@progbits
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB13:
    .cfi_startproc
    subq    $24, %rsp
    .cfi_def_cfa_offset 32
    movl    $.LC0, %edi
    xorl    %eax, %eax
    leaq    12(%rsp), %rsi
    call    scanf
    movl    $.LC1, %edi
    call    puts
    xorl    %eax, %eax
    addq    $24, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE13:
    .size   main, .-main
    .ident  "GCC: (Debian 4.6.3-1) 4.6.3"
    .section    .note.GNU-stack,"",@progbits