Неявная внутренняя связь не такая, как явная внутренняя связь («статическая»)? - PullRequest
9 голосов
/ 30 июня 2011

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

Некоторые массивы внутри исходного файла указывают на строковые литералы, например:

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 уже доступен только для чтения, inhowfar static const «более доступен только для чтения» (один входит в .rdata, а другой - нет)?

1 Ответ

7 голосов
/ 30 июня 2011

Ваши массивы не объявлены const, следовательно, они также не являются неявно внутренними связями. То, что у вас есть, это неконстантные массивы указателей на константы.

Тем не менее, я не знаю, почему это влияет на то, заканчиваются ли строки в .rdata или .data.

...