在通过值传递const参数的情况下,是否有任何实际的优化优势示例?

Laz*_*eus 5 c optimization const c99

情况就是这样,

我试图调查实现函数的一些优点/缺点,如下所示:

void foo(const int a, const int b)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

使用通用函数原型作为API,它包含在头文件中,如下所示:

void foo(int a, int b)
Run Code Online (Sandbox Code Playgroud)

我在下面的问题中找到了关于这个主题的大量讨论:

类似问题

我同意rlerallut的回答,他说的是自我记录代码,并且在代码的安全性方面有点偏执.

然而,这是一个问题,有人在那里写道,使用const传递给函数的常用参数可以带来一些优化的好处.我的问题是,是否有人有现实生活中的例子来证明这一主张?

old*_*mer 2

“它可能会帮助编译器稍微优化一些东西(尽管可能性不大)。”

我看不出这会产生什么影响。在这种情况下,当您尝试修改 const 变量时生成编译器警告/错误是最有用的...

如果您试图发明一个实验来比较声明为 const 或非 const 的函数参数以达到优化目的,请按值传递。这意味着该实验不会修改变量,因为使用 const 时您会收到警告/错误。可能能够关心的优化器已经知道该变量在有或没有声明的代码中都没有被修改,然后可以采取相应的行动。该声明有何影响?如果我发现这样的事情,我会将差异作为错误提交到编译器错误板。

例如,这是我在使用 const 与 not 时发现的一个错失的机会。

注意 const 与否并不重要...

void fun0x ( int a, int b);
void fun1x ( const int a, const int b);
int fun0 ( int a, int b )
{
    fun0x(a,b);
    return(a+b);
}
int fun1 ( const int a, const int b )
{
    fun1x(a,b);
    return(a+b);
}
Run Code Online (Sandbox Code Playgroud)

gcc 使用 -O2 和 -O3(和 -O1?)生成

00000000 <fun0>:
   0:   e92d4038    push    {r3, r4, r5, lr}
   4:   e1a05000    mov r5, r0
   8:   e1a04001    mov r4, r1
   c:   ebfffffe    bl  0 <fun0x>
  10:   e0850004    add r0, r5, r4
  14:   e8bd4038    pop {r3, r4, r5, lr}
  18:   e12fff1e    bx  lr

0000001c <fun1>:
  1c:   e92d4038    push    {r3, r4, r5, lr}
  20:   e1a05000    mov r5, r0
  24:   e1a04001    mov r4, r1
  28:   ebfffffe    bl  0 <fun1x>
  2c:   e0850004    add r0, r5, r4
  30:   e8bd4038    pop {r3, r4, r5, lr}
  34:   e12fff1e    bx  lr
Run Code Online (Sandbox Code Playgroud)

如果这会以更少的周期起作用......

push {r4,lr}
add r4,r0,r1
bl fun1x
mov r0,r4
pop {r4,lr}
bx lr
Run Code Online (Sandbox Code Playgroud)

clang/llvm 做了同样的事情,即在函数调用燃烧额外的堆栈位置后添加。

谷歌搜索主要显示了关于引用 const 而不是值 const 的讨论,然后是 C 和 C++ 的细微差别,即 const 声明会或不会或可以或不能改变什么,等等。

如果您在全局变量上使用 const,那么它可以将该项目保留在 .text 中,而不将其保留在 .data 中(对于您的 STM32 微控制器,不必将其从闪存复制到 RAM)。但这不符合你的规则。优化器可能不关心,也可能不会真正接触到该变量,它可能知道将其直接编码到指令中,作为基于指令集的立即数,等等......所有事物都保持不变,尽管非常量会具有如果没有声明为易失性,则具有相同的好处...

按照您的规则,const 可以避免一些人为错误,如果您尝试将该 const 变量放在等号的左侧,编译器会让您知道。

我认为这违反了您的规则,但是如果在按值传递的函数内部,您会执行一些按引用传递的操作,并玩按引用传递 const 与非优化游戏......