Накладные расходы на модификатор const для встроенных типов в C ++ - PullRequest
4 голосов
/ 19 марта 2012

Я предпочитаю добавлять модификатор const ко всем встроенным аргументам в функциях, которые я пишу.Например:

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

лучше для меня, чем:

void foo(int arg1, double arg2);

После обзора кода мне сказали, что модификатор const приводит к издержкам, когда он применяется к целочисленным и встроеннымтипы.Это правда и почему?

Спасибо,

Ответы [ 8 ]

7 голосов
/ 19 марта 2012

Он имеет не больше накладных расходов, чем typedef. Ваш коллега не прав.

Если вы хотите убедить его, распечатайте разборку обоих вариантов и покажите коллеге, что они одинаковые .

Однако добавление квалификатора const к таким примитивным типам совершенно бессмысленно и бесполезно. Они все равно копируются, и их изменение не повредит. Ничего не получится сделать их постоянными.

4 голосов
/ 19 марта 2012

Нет никаких накладных расходов с 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):

Для 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   : }
3 голосов
/ 19 марта 2012

Это не правда.

Независимо от этого, вы не должны помещать 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
}
2 голосов
/ 19 марта 2012

После проверки кода мне сказали, что модификатор const приводит к накладным расходам, когда он применяется для целочисленных и встроенных типов. Это правда и почему?

Кому вы дали свой код для его просмотра? Младший программист?

Выше не соответствует действительности. Наоборот. Использование const может привести к некоторой оптимизации.

2 голосов
/ 19 марта 2012

Это не правда. 1

Или, точнее, я не могу придумать причину, по которой это может быть правдой.Все, что const делает, это заставляет компилятор проверять, что вы не меняете значение переменной;но это проверка во время компиляции.


1.Предполагая, что мы используем традиционное определение «издержек», которое относится к производительности во время выполнения или размеру скомпилированного кода.
1 голос
/ 19 марта 2012

Это может принести накладные расходы, если вынуждает вас создать дополнительную локальную переменную.

Без констант

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

    // use arg2
}

С константой

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

    // use arg2Copy
}

Но это действительнозависит от компилятора.Если вы беспокоитесь о накладных расходах, вам следует сравнить сгенерированный код.

1 голос
/ 19 марта 2012

Какой тип накладных расходов вы имеете в виду? Накладные расходы для скомпилированного двоичного файла или накладные расходы компилятора? Я уверен, что скомпилированный двоичный файл идентичен для первого и второго примеров кода, которые вы добавили. Для компилятора - возможно. Const добавляет дополнительные условные выражения, которые должны быть проверены во время компиляции.

1 голос
/ 19 марта 2012

Нет, это не правда.

Я думаю, что вы / они путали const с передачей по ссылке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...