C ++中内置类型的const修饰符的开销

时间:2012-03-19 09:37:31

标签: c++ const overhead

我更喜欢将const修饰符添加到我编写的函数中的所有内置参数中。 E.g:

void foo(const int arg1, const double arg2);

比我更好:

void foo(int arg1, double arg2);

在代码审查之后,我被告知const修饰符在应用于整数和内置类型时会带来开销。这是真的吗?为什么?

谢谢,

8 个答案:

答案 0 :(得分:7)

它没有typedef的开销。你的同事错了。

如果你想说服他,打印出两种变体的反汇编,并向同事展示他们是相同的

然而,将const限定符添加到这样的基本类型是完全没有意义和徒劳的。无论如何它们都被复制了,修改它们没有任何害处。把它们变成const是没有任何好处的。

答案 1 :(得分:4)

const没有任何开销,我猜你的同事只是与使用混淆,因为它(不幸的是)并不常见。就个人而言,我更喜欢const尽可能多的局部变量,因为它增加了可读性。

当然,反驳总是很容易,采用以下程序并使用汇编输出进行编译:

#include <stdio.h>

void foo1(int a, double b)
{
  printf("Not const %d, %g\n", a, b);
}

void foo2(const int a, const double b)
{
  printf("Const %d, %g\n", a, b);
}


int main()
{
  for(int i = 0; i < 10; ++i)
  {
    foo1(i, 5.5 * i);
    foo2(i, 12.8 * i);
  }
  return 0;
}

为这些函数生成的汇编代码完全相同(使用VS2010 release-build):

对于foo1(没有const - 说明符):

; 4    : {

push    ebp
mov     ebp, esp

; 5    :    printf("Not const %d, %g\n", a, b);

fld     QWORD PTR _b$[ebp]
sub     esp, 8
fstp    QWORD PTR [esp]
push    eax
push    OFFSET ??_C@_0BC@FACFPKBC@Not?5const?5?$CFd?0?5?$CFg?6?$AA@
call    DWORD PTR __imp__printf
add     esp, 16                 ; 00000010H

; 6    : }

对于foo2(使用const - 说明符):

; 9    : {

push    ebp
mov     ebp, esp

; 10   :    printf("Const %d, %g\n", a, b);

fld     QWORD PTR _b$[ebp]
sub     esp, 8
fstp    QWORD PTR [esp]
push    eax
push    OFFSET ??_C@_0O@LOLEPDHC@Const?5?$CFd?0?5?$CFg?6?$AA@
call    DWORD PTR __imp__printf
add     esp, 16                 ; 00000010H

; 11   : }

答案 2 :(得分:3)

事实并非如此。

独立于此,您不应将const放入函数声明,因为它是一个实现细节:它只限定 local 变量。功能范围。所以你可以这样写:

double foo(unsigned int a, double b);  // declaration

double foo(unsigned int const a, double b)  // implementation
{
    b *= a;
    return bar(b);   // silly example
}

答案 3 :(得分:2)

不是这样。 1

或者,更准确地说,我无法想出它为什么会成真的原因。所有const都会强制编译器检查您是否没有更改变量的值;但那是一次编译时检查。

<小时/> <子> 1。假设我们正在使用与运行时性能或编译代码大小相关的传统“开销”定义。

答案 4 :(得分:2)

  

在代码审查之后,我被告知const修饰符在应用于整数和内置类型时会带来开销。这是真的吗?为什么?

您提供的代码是谁进行审核的?一名初级程序员?

以上情况并非如此。恰恰相反。使用const可能会应用一些优化。

答案 5 :(得分:1)

不,那不是真的。

我认为你/他们把const与传递参考混淆了。

答案 6 :(得分:1)

你是什么类型的开销? 编译二进制或编译器开销的开销?我确信已编译的二进制文件对于您添加的第一个和第二个代码示例是相同的。对于编译器 - 也许。 Const添加了额外的条件,必须在编译时检查。

答案 7 :(得分:1)

如果它迫使你创建一个额外的局部变量,它会带来开销。

没有const

void foo(const int arg1, double arg2)
{
    if (arg1 == 1)
        arg2 += 5.0;

    // use arg2
}

使用const

void foo(const int arg1, const double arg2)
{
    double arg2Copy;
    if (arg1 == 1)
        arg2Copy = arg2 + 5.0;
    else
        arg2Copy = arg2;

    // use arg2Copy
}

但这实际上取决于编译器。如果您担心开销,则应比较生成的代码。