Const modifier overhead for built-in types in C ++

I prefer to add a modifier const

to all inline arguments in the functions I write. For example:.

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

      

is better for me than:

void foo(int arg1, double arg2);

      

After looking at the code, I was told that the modifier const

incurs overhead when applied to integer and built-in types. Is this true and why?

Thank,

+3


source to share


8 answers


It has no more overhead than typedef

. Your colleague is wrong.

If you want to convince him, print out a breakdown of both options and show your colleague that they are the same.



However, adding a classifier const

to such primitive types is completely pointless and useless. They are copied anyway and there is no harm in changing them. It won't work by making them const.

+6


source


There is no overhead with const

, I think your employees are just confused about the use as it is (unfortunately) not that common. Personally, I prefer const

as many local variables as possible as it improves readability.

Of course, it is always easy to disprove, execute the following program and compile it using assembly:

#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;
}

      

The summary code generated for these functions is exactly the same (using VS2010 build):



For foo1

(no const

-specifications):

; 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    : }

      

For foo2

(with const

-specifiers):

; 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   : }

      

+4


source


This is not true.

Regardless, you should not put const

a function in the declaration, as this is an implementation detail: it only qualifies the local variable in the function scope. Therefore, you can write it like this:

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


source


This is not true. 1

Or rather, I can't think of why this might be true. Everyone const

really makes the compiler check that you are not changing the value of the variable; but this is a compile time check.


<sub> 1. Assuming we are using the traditional definition of "overhead", which refers to execution performance or compiled code size.
+2


source


After looking at the code, I was told that the constant modifier brings an overhead when applied to integer and built-in types. Is this true and why?

Who did you give your code to to view it? Junior Programmer?

The above is not true. On the contrary. Using const can lead to some optimization.

+2


source


No, it is not.

I think you / they are confusing const with passing by reference.

+1


source


What type of invoice do you mean? Overhead for compiled binary or compiler overhead? I'm pretty sure the compiled binary is identical for the first and second code samples you added. For the compiler, maybe. Const adds additional conditional values ​​that must be checked at compile time.

+1


source


This can lead to overhead if it forces you to create an additional local variable.

No const

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

    // use arg2
}

      

With const

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

    // use arg2Copy
}

      

But it really depends on the compiler. If you are concerned about the overhead, you should compare the generated code.

+1


source







All Articles