Насколько я понимаю, в C ++ рекомендуется определять переменные с наименьшей возможной областью действия.
Насколько я понимаю, основная причина этого заключается в том, что это поможет предотвратить случайное повторное использование. Кроме того, за это почти никогда не случается снижение производительности (или мне так сказали). Напротив, люди, кажется, указывают, что компилятор может фактически производить эквивалентный или лучший код, когда переменные определяются локально. Например, следующие две функции производят одинаковые двоичные файлы в Godbolt :
#include <cstdio>
#include <cstdlib>
void printRand1() {
char val;
for (size_t i = 0; i < 100 ; ++i) {
val = rand();
puts(&val);
}
}
void printRand2() {
for (size_t i = 0; i < 100 ; ++i) {
const char val = rand();
puts(&val);
}
}
Так что в этом случае версия 2 явно предпочтительнее. С этим контекстом я могу полностью согласиться и понять.
Что мне не понятно, так это то, следует ли применять ту же логику к более крупным типам данных, таким как массивы или векторы. Одна особенность, которую я нахожу в коде, - это что-то вроде этого:
#include <cstdio>
#include <cstdlib>
#include <vector>
struct Bob {
std::vector<char> buffer;
void bar(int N) {
buffer.resize(N);
for (auto & elem : buffer) {
elem = rand();
puts(&elem);
}
}
};
void bob() {
Bob obj;
obj.bar(100);
}
, несмотря на тот факт, что мы могли бы лучше локализовать данные в этом тупом примере:
#include <cstdio>
#include <cstdlib>
#include <vector>
struct Bob {
void bar(int N) {
std::vector<char> buffer(N);
for (auto & elem : buffer) {
elem = rand();
puts(&elem);
}
}
};
void bob() {
Bob obj;
obj.bar(100);
}
Примечание: прежде чем вы, ребята, начнете это делать, я полностью понимаю, что вам на самом деле не нужен вектор в этом примере. Я просто делаю глупый пример, чтобы двоичный код не был слишком большим на Godbolt.
Обоснование того, что НЕ локализовать данные (он же фрагмент кода 1), состоит в том, что буфер может быть каким-то большим вектором, и мы не хотим перераспределять его каждый раз, когда вызываем функцию.
Обоснованием для Snippet 2 является лучшая локализация данных.
Так какую логику я должен применить для этого сценария? Меня интересует случай, когда вам на самом деле нужен вектор (в данном случае вам это не нужно).
Должен ли я следовать логике локализации? или я должен следовать логике, что я должен попытаться предотвратить повторные перераспределения?
Я понимаю, что в реальном приложении вы бы хотели оценить производительность, а не скомпилированный размер в Godbolt. Но мне интересно, каким должен быть мой стиль по умолчанию для этого сценария (до того, как я начну профилировать код).