Есть ли польза от объявления const, а не переменной внутри функции? - PullRequest
7 голосов
/ 04 августа 2011

Если у меня есть функция, которая существует только в течение короткого промежутка времени, делает ли список цветов постоянным значение?

string getrandcolor(){
    const string colors[5] = {"red", "blue", "green", "yellow", "purple"};
    return colors[rand() % 5];
}

Примечание: фактический список цветов содержит сотни цветовне только маленький образец, который я показал, не уверен, что это также имеет значение.

Ответы [ 6 ]

16 голосов
/ 04 августа 2011

Это предотвращает случайную перезапись переменных, которые вы не хотели менять. «Упс!» - защита, пожалуй, самая важная функция const.

Гипотетически, компилятор может угадать какую-то оптимизацию, зная, что переменная не должна изменяться, но в моем тестировании никогда не было найдено такой, которая действительно что-то значило бы в описываемой вами ситуации.

const static имеет важное различие в вашем конкретном примере кода. Поскольку ваш массив colors [] является локальным, он должен создаваться заново каждый раз, когда вызывается функция getrandcolor(). Это означает, что строковой конструктор запускается пять раз при каждом вызове getrandcolor(), что очень расточительно. const static означает, что данные создаются только один раз & mdash; при первом запуске функции & mdash; и положить в общую память.

6 голосов
/ 04 августа 2011

С точки зрения производительности? Нет, наверное нет. Похоже, ваш массив тоже может быть static, а затем, возможно, да .

С точки зрения стиля кода? Возможно. Хотя добавление const делает ваш код немного многословным, оно также дает понять, что данные не подлежат изменению. Это документация и сейф .


В идеале все объекты в C ++ должны быть константами по умолчанию, и вам придется написать mutable, чтобы сделать их переменными. Это все задом наперед!

2 голосов
/ 04 августа 2011

Говоря о производительности, а также о читабельности кода, вы должны создать переменную «colors» вне функции (поскольку массив размером в сотню - это довольно большой объем кода, маскирующий логику функции) либо в функции инициализацииили на глобальном уровне.Если вы не планируете извлекать эту переменную, по крайней мере, сделайте ее статической.

Если этот массив используется только в течение короткого периода времени во время выполнения программы, вы можете рассмотреть возможность его заполнения до первого вызова getcolorsв конце концов освободите его, когда будете уверены, что вам это больше не понадобится.

2 голосов
/ 04 августа 2011

Объявляя локальную переменную const, вы получаете следующие преимущества:

  • Правильность: компилятор позаботится о том, чтобы вы случайно не изменили значение переменной.
  • Ясность: вы четко документируете, что переменная является константой.

(Кстати, я не уверен, что константа в этом конкретном примере. Скоро ...)

2 голосов
/ 04 августа 2011

Если вы говорите о производительности, то: нет , это не должно иметь никакого значения.

1 голос
/ 04 августа 2011

Немного другой пример:

const int *global_ptr = 0;

void bar();

void foo() {
    int x = 1;
    global_ptr = &x;
    bar();
    std::cout << x << "\n";
}

Компилятор не может оптимизировать последнюю строку, чтобы использовать значение 1, потому что для всех известных ему bar() принимает значение global_ptr, преобразует егона int* и изменяет x через него.Это было бы несколько рискованным кодированием, но исключение квалификатора const и мутирования допустимо при условии, что ссылка на действительно изменяемый объект, поэтому компилятор должен допустить это.

Но, если x помечено constтогда будет недопустимым , чтобы bar() отбрасывал const и мутировал, и поэтому оптимизатор может предположить, что x по-прежнему содержит значение 1 при печати. ​​

Оптимизаторы, безусловно, идентифицируют константы времени компиляции для такого рода оптимизации, поэтому я не удивлюсь, увидев, что это имеет значение для испускаемого кода.Насколько это влияет на производительность, я не знаю.Нетрудно сгенерировать случаи, когда идентификация константы может, например, заменить (дорогое) деление на некоторое (более дешевое) переворот в битах, или может позволить выражениям, включающим x и кучу других констант, вычисляться во время компиляции, а не во время выполнения..

Кроме того, оптимизация времени соединения может позволить встроить bar, и в этом случае оптимизатор времени соединения может более тщательно проверять свое содержимое и может исключить возможность изменения xв неконстантном случае.

В вашем примере, однако, никакая ссылка на colors не может скрыться от неизвестного кода, поэтому разница не возникает.В любом случае, const-строку, вероятно, сложнее оптимизировать, чем const int, поэтому вероятность того, что вы включите блестящую оптимизацию с помощью const.

, еще меньше.
...