Сегодня я столкнулся с особенностью, которая, может быть, и не очень важна, но тем не менее меня озадачивает. Может быть, я просто неправильно понимаю С++.
Некоторые массивы внутри исходного файла указывают на строковые литералы, например:
const char* a[] = { "a", "b", "c" };
const char* b[] = { "d", "e"};
const char* c[] = { "f", "g"};
Ни один из этих массивов указателей никогда не используется каким-либо образом, кроме передачи в GetProcAddress
для извлечения указателя функции из библиотеки (это неблокирующий динамический загрузчик функций OpenAL/EFX/capture и создатель/менеджер контекста).
В конце концов мне пришло в голову, что я, вероятно, должен объявить эти переменные как static const
, поскольку они не нужны нигде за пределами этого самого файла .cpp, поэтому явное внутреннее связывание казалось уместным. В любом случае они должны иметь внутреннюю связь (ISO14882 3.5(3)), так что мы только ведем себя как добропорядочные граждане, явно указывая на то, что компилятор уже предполагает.
Выполнение этого невинного изменения привело к увеличению размера исполняемого файла на 512 байт. Не то чтобы дополнительные 512b действительно имели значение, просто казалось нелогичным, что одна и та же вещь приведет к другому коду. Поскольку static const
устарело (ISO14882 7.3.1.1(2)), я также попробовал анонимное пространство имен с тем же результатом.
Глядя на исходный код ассемблера, видно, что явное внутреннее связывание (static
или namespace{}
) переместит строковые литералы в .rdata
, а не .data
, а строковые литералы чередуются с массивами указатель-строка-литерал вместо того, чтобы иметь все строки и все указатели. в одном блоке соответственно. В этом, вероятно, и заключается причина разного размера — очень вероятно, что при перетасовке данных из одного раздела в другой возникло ограничение размера раздела. Интересно, что все 3 вкуса по-разному искажают названия.
Теперь мне интересно: не ошибаюсь ли я, должны ли эти указатели не иметь внутреннюю связь?
Кроме того, в моем понимании const
уже доступен только для чтения, насколько static const
"более доступен только для чтения" (один входит в .rdata
, а другой нет)?