SCCS строки "что" не оптимизированы компилятором - PullRequest
3 голосов
/ 27 января 2009

Мы пытаемся встроить строку what в двоичные объекты, чтобы мы могли видеть номер версии для развернутой исполняемой или разделяемой библиотеки. Обычно мы встраиваем стандартную информацию CVS Id в эту строку. Например, мы можем встроить:

const char cvsid[] = "@(#)OUR_TEAM_staging_remap_$Revision: 1.30 $ $Name:  $";

в коде C.

От человека (1) что:

Утилита what ищет каждое имя файла в поисках шаблон @ (#), который получает команда SCCS (см. sccs-get (1)) заменяет ключевое слово @ (#) ID и печатает следующее до символа ",>, NEWLINE, \ или NULL.

Существует только один экземпляр этой переменной, и на него никогда не ссылаются. Кто-то предположил, что это может быть оптимизировано компилятором.

Я уже много лет использую эту технику в C и C ++ и с различными компиляторами, и мне еще предстоит увидеть, какая строка оптимизирована.

Кто-нибудь понял, почему они не оптимизированы?

Ответы [ 6 ]

2 голосов
/ 31 января 2009

До недавнего времени (я заметил проблему в середине 2005 года) можно было использовать:

static const char sccs[] = "@(#)%W% %E%";

или что-то подобное в исходном коде и GCC, и большинство других компиляторов не оптимизируют его. Начиная с выпуска GCC примерно с того времени (вероятно, GCC 4.0.x, созданного в апреле 2005 года), эти постоянные строки были исключены из двоичных файлов. Итак, мне пришлось изменить исходный код, чтобы переменные были видны извне. Компилятор не может просмотреть только объектный файл и сделать вывод, что строка не используется, потому что что-то вне файла может предположительно ссылаться на него. Итак, мои файлы теперь содержат:

#ifndef lint
extern const char jlss_id_filename_c[];
const char jlss_id_filename_c[] = "@(#)$Id$";
#endif /* lint */

ОК - это гибрид; Я действительно использую RCS для хранения исходного кода, но я все еще предпочитаю what - ident для идентификации файлов - плюс у меня есть собственный взломанный what, который делает и 1010 *, и ident плюс несколько настроек моего своя. Но у меня есть объявление в некоторых файлах - не во всех - и определение во всех файлах. (При некотором наборе флагов предупреждений, которые сейчас не запоминаются, я получал предупреждения, когда переменная была определена до ее объявления. Возможно, это было изменение в GCC, которое решило эту проблему; я больше не уверен.)

Когда я создаю новый файл, мой генератор шаблонов заменяет «filename_c» на соответствующее имя генерируемого файла. Аналогично для заголовков - хотя строка идентификации встроена только в один файл, чтобы избежать нескольких определений.

Я предпочел старую систему со статическими константами - но это работало для меня более 3 лет.

2 голосов
/ 27 января 2009

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

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

Оптимизируя такую ​​строку в вашем приложении, я полагаю, что поведение не изменится. Но компиляторы хотят быть удобными в использовании и стараются не наносить ударов по пользователям. Вот почему они также содержат полезные расширения. Если вы хотите быть уверены, что он не оптимизирован, возможно, посмотрите расширения компиляторов. GCC имеет атрибут unused, который не дает предупреждений для неиспользуемых объектов. Может быть, это или что-то подобное может помочь вам, что переменная не оптимизирована.

С точки зрения языка, нет утилиты, которая заставляет компилятор сохранять ее.

Редактировать : На эту тему был пост из usenet здесь с полезными ответами.

2 голосов
/ 27 января 2009

Как правило, этого не происходит, потому что посторонние строки имеют небольшую стоимость и могут быть полезны в таких случаях, как этот, среди прочего (например, хранение набора строковых ресурсов с использованием только первых, фактически указанных в коде).

1 голос
/ 04 августа 2015

(Да, я знаю, что об этом спрашивали и отвечали давным-давно. Но этот новый стиль ответа доступен, так что ...)

В gcc (по крайней мере, в 3.3 и последующих) теперь есть директива компилятора __attribute__((unused)), чтобы пометить переменную как "известную, что на нее может не быть ссылка" для подавления предупреждений, __attribute__((used)) чтобы пометить его как использованный (и, следовательно, не использовать для оптимизации), даже если никакой другой код не ссылается на него.

Так что это может сделать это для вас:

static const char what_ident[] __attribute__((used)) = "@(#) $Id$";

Если linker все еще оптимизирует его, то вам может потребоваться поместить его в раздел, помеченный как keep независимо от ссылок на время ссылки.

static const char what_ident[] __attribute__((section("what"), used)) = "@(#) $Id$";

и добавьте параметр gcc -Wl,-bkeepfile:file.o, чтобы компоновщик не подавлял разделы, на которые нет ссылок, в выходных данных file.c.

1 голос
/ 22 июля 2009

Без ключевого слова «static» переменная не может быть оптимизирована, потому что другой модуль может объявить ссылку на нее (используя extern). Поскольку C / C ++ обычно компилируется в файл за раз, компилятор не может узнать, существует ли внешняя ссылка.

Добавляя ключевое слово static, вы сообщаете компилятору, что имя видно только внутри компиляции, и его оптимизация становится возможной.

Я думаю, что компоновщик может обнаружить неиспользуемую глобальную переменную и оптимизировать ее тоже, если формат объекта позволяет это, хотя я не уверен, что кто-либо делает.

1 голос
/ 27 января 2009

Microsoft Visual C ++ 2005 имеет опцию компоновщика, которая должна управлять тем, что он делает с неиспользуемыми данными: /OPT:UNREF заставляет компоновщик сохранять неиспользуемые данные, /OPT:REF позволяет ему удалять их.

Однако в моем простом тесте этот параметр не оказал влияния на утверждение

static char VersionString[] = "HELLO_WORLD 2.0";

Строка появилась в двоичных файлах выпуска и отладки независимо от флага.

...