C ++ стандартное и глобальное удаление символов - PullRequest
1 голос
/ 10 января 2009

Кто-нибудь имеет ссылку на то, что говорит стандарт C ++ относительно компилятора, удаляющего глобальные и статические символы? Я думал, что вы не были уверены, что компилятор удалит глобальные символы, если на них нет ссылок. Мой коллега утверждает, что если ваши глобальные символы включены в основную единицу перевода, эти символы не будут удалены, даже если на них нет ссылок.

Ответы [ 3 ]

3 голосов
/ 10 января 2009

Интересно, что все, что я могу найти по этому поводу в стандарте C ++ 2003, это:

3.7.1 Статическая продолжительность хранения [basic.stc.static]

Все объекты, которые не имеют динамического длительность хранения, ни местные статическая продолжительность хранения. Хранение для этих объектов будет продолжаться для продолжительность программы (3.6.2, 3.6.3).

Если объект статического хранения продолжительность имеет инициализацию или деструктор с побочными эффектами, он должен не будет устранено, даже если оно появится быть неиспользованным, за исключением того, что класс объект или его копия могут быть устранены как указано в 12,8.

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

Если есть более прямое разрешение, я его не видел (но, возможно, кто-то еще увидит).

Однако следует отметить, что использование компоновщика для удаления неиспользуемых объектов в конечном изображении является очень распространенной оптимизацией.

0 голосов
/ 10 января 2009

Мне кажется, именно так (ранее мы долго обсуждали этот вопрос о переполнении стека в ветке комментариев):

  1. Если инициализация или деструктор объекта с областью пространства имен (которые являются объектами со статической продолжительностью хранения) не имеет побочных эффектов, объект может быть оптимизирован, если в его блоке перевода не используется функция или объект.
  2. Для объектов, инициализация или уничтожение которых вызывает побочные эффекты, компилятор может не оптимизировать эту переменную, даже если не используются объекты или функции ее единиц перевода.

В любом случае, компилятор должен инициализировать объекты до того, как это будет сделано, но не обязательно до main. Я проводил тесты, потому что кто-то из stackoverflow сказал, что gcc эффективно оптимизирует инициализацию объектов, имеющих побочные эффекты, если такого применения нет. Я проверял это сейчас, и я видел, что gcc этого не делает. Кроме того, насколько я понимаю Стандарт, в любом случае это запрещено.

Достаточно, если вы просто берете адрес объекта или функции единицы перевода объекта, который вы хотите инициализировать. Чтобы быть в безопасности, лучше всегда делать это, даже для объектов, имеющих инициализации с побочными эффектами. Предполагая, что ваш друг прав, я думаю, что для единицы перевода main, main всегда рассматривается как используется , так что условие немедленно удовлетворяется. Правила можно найти в 3.6.2p3, 3.7.1p2 и 3.2p2 (определение использовать ), 1.9p7 (определение побочный эффект ).

0 голосов
/ 10 января 2009

Вы задаете вопрос о связывании, и хотя в стандарте C ++ говорится, что связывание должно происходить как финальная фаза перевода, ничего не говорится о как , что должно произойти. Например, в нем говорится, что ссылки на функции разрешены, но не требуется, чтобы они разрешались по имени, и не говорится, что происходит со ссылками после разрешения.

Чтобы определить, какие символы компилятор включает в объектный код, а какие компоновщик удаляет или не удаляет, вам необходимо обратиться к документации для компилятора и компоновщика, соответственно, которые вы используете.

...