я вижу, картина последующих происходит довольно часто:Повторяющиеся литералы и жесткое кодирование
b->last = ngx_cpymem(b->last, "</pre><hr>", sizeof("</pre><hr>") - 1);
Обратите внимание, что символьная строка используется дважды. Экстракт из исходной базы nginx.
Компилятор должен иметь возможность объединить эти литералы, когда он встречается внутри блока компиляции.
Мои вопросы:
- ли составители коммерческого класса (VC++, GCC, LLVM/Clang) удалить эту избыточность, когда встречаются в пределах единицы компиляции?
- Удаляет ли (статический) компоновщик такие сокращения при связывании объектных файлов.
- Если 2 применяется, эта оптимизация возникает во время динамической компоновки?
- Если применяются 1 и 2, применяются ли они ко всем литералам.
Эти вопросы важны, потому что это позволяет программисту быть многословным без потери эффективности, т. Е. Думать о том, что огромные статические модели данных жестко подключены к программе (например, правила системы поддержки принятия решений, используемые в некоторый низкоуровневый сценарий).
Редактировать
2 точки/разъяснения
Код выше написано признанным "мастер" программистом. Парень в одиночку написал nginx.
Я не спрашивал, какой из возможных механизмов буквального жесткого кодирования лучше. Поэтому не уходите из темы.
Edit 2
Мой оригинальный пример был довольно надуманным и ограничительный характер. Следующий фрагмент показывает использование строковых литералов, встроенных в внутренние жестко кодированные знания. Первый фрагмент предназначен для синтаксического анализатора, сообщающего ему, какие значения перечисления задавать для какой строки, а второй для более общего использования в качестве строки в программе. Лично я доволен этим, пока компилятор использует одну копию строкового литерала, и поскольку элементы являются статическими, они не входят в глобальные таблицы символов.
static ngx_conf_bitmask_t ngx_http_gzip_proxied_mask[] = {
{ ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF },
{ ngx_string("expired"), NGX_HTTP_GZIP_PROXIED_EXPIRED },
{ ngx_string("no-cache"), NGX_HTTP_GZIP_PROXIED_NO_CACHE },
{ ngx_string("no-store"), NGX_HTTP_GZIP_PROXIED_NO_STORE },
{ ngx_string("private"), NGX_HTTP_GZIP_PROXIED_PRIVATE },
{ ngx_string("no_last_modified"), NGX_HTTP_GZIP_PROXIED_NO_LM },
{ ngx_string("no_etag"), NGX_HTTP_GZIP_PROXIED_NO_ETAG },
{ ngx_string("auth"), NGX_HTTP_GZIP_PROXIED_AUTH },
{ ngx_string("any"), NGX_HTTP_GZIP_PROXIED_ANY },
{ ngx_null_string, 0 }
};
внимательно следил:
static ngx_str_t ngx_http_gzip_no_cache = ngx_string("no-cache");
static ngx_str_t ngx_http_gzip_no_store = ngx_string("no-store");
static ngx_str_t ngx_http_gzip_private = ngx_string("private");
до тех, которые остались на тему, браво!
Извините, но вы беспокоитесь, что высокооктановое топливо заставит машину двигаться быстрее, но не учитывая, что дорога заполнена отверстиями в горшках. Выберите лучшую дорогу, поставив свои литералы в константы. (ОК не лучшая метафора когда-либо, но она работает на точку) –
Почему вы ** хотите ** повторить себя в своем коде? Гораздо лучший вопрос: «Можно ли ** избегать ** быть многословным, не теряя эффективности?» – jalf
Хотя мне придется согласиться с jalf (программистом «master» или нет), ответ на ваш вопрос «да», все достойные компиляторы будут не только объединять дублированные строковые литералы в одной и той же единицы перевода, но и компоновщик также объединит дубликаты через единицы перевода. Это справедливо даже для датированных компиляторов, таких как CW 8, которые предоставляют это как вариант компоновщика. Конечно, этого не произойдет, конечно, в разделяемых библиотеках/библиотеках DLL. Однако, если ваш код зависит от дублированных строковых литералов, чтобы разделить один и тот же адрес, тогда код будет катастрофой в ожидании. – stinky472