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