重复文字和硬编码

Has*_*yed 3 c c++ compiler-theory micro-optimization string-interning

我发现以下模式经常发生:

 b->last = ngx_cpymem(b->last, "</pre><hr>", sizeof("</pre><hr>") - 1);
Run Code Online (Sandbox Code Playgroud)

请注意,文字字符串使用了两次.提取物来自nginx源库.

在编译单元中遇到这些文字时,编译器应该能够合并这些文字.

我的问题是:

  1. 当在编译单元中遇到时,商业级编译器(VC++,GCC,LLVM/Clang)是否会删除此冗余?
  2. 链接目标文件时,(静态)链接器是否会删除此类冗余.
  3. 如果2适用,这种优化会在动态链接期间发生吗?
  4. 如果1和2适用,它们是否适用于所有文字.

这些问题很重要,因为它允许程序员在不损失效率的情况下进行冗长 - 即,考虑将大量静态数据模型硬连接到程序中(例如,某些低级方案中使用的决策支持系统的规则) .

编辑

2分/澄清

  1. 上面的代码由公认的"主"程序员编写.这家伙一手写了nginx.

  2. 我没有问过文字硬编码的哪种可能机制更好.所以不要偏离主题.

编辑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 }
};
Run Code Online (Sandbox Code Playgroud)

紧随其后:

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");
Run Code Online (Sandbox Code Playgroud)

对于那些留在话题上的人,勇敢!

caf*_*caf 8

请注意,对于特定情况sizeof("</pre><hr>"),几乎可以肯定字符串文字将永远不会出现在输出文件中 - 整个sizeof表达式可以在编译时计算为整数常量11.

尽管如此,编译器合并相同的字符串文字仍然是一种非常常见的优化.

  • `sizeof`表达式是一个编译时常量(按照C++标准).所以"几乎可以肯定"似乎是轻描淡写. (2认同)

Pat*_*ick 7

在这种情况下,我无法回答你的问题,但总是尝试使用const字符串(甚至#define会更好).问题出现在你重构代码并改变一个文字的值而忘记了另一个时(在你的例子中不太可能,因为它们彼此相邻,但我之前已经看过).

无论编译器可以做什么的人工操作,人类仍然可以开玩笑:)

  • 其实我只是想帮忙,但是嘿. (3认同)
  • 最后一行一百万次,其余部分也是如此!冗余尖叫'这里插入错误'. (2认同)
  • 啊,我希望我能够成熟,但我没有:).我相信人们在搜索这些复杂代码的内部时会知道,常量上的sizeof()会被优化,但这是你选择的答案; 也许提供基本信息有时甚至可以对像你这样的专家有用,我向你保证,当我提出我的时候,我并不是要质疑你的专业知识. (2认同)
  • 最后,我倾向于冒险激怒专家,提供他们不需要的建议,而不是试图帮助那些做过的人 (2认同)
  • 那很好,我很乐意为大多数事情辩论而且不容易被冒犯.我认为你已经混淆了你的定义,隧道愿景将纯粹集中于这个问题而不考虑潜在的更广泛的问题; 至于长期有效性只是因为你没有找到有用的东西并不意味着没有其他人会这样做. (2认同)

unb*_*eli 5

  1. 对海湾合作委员会(YCC)是,其他国家也应如此
  2. 对于GNU链接器可能是肯定的(请参阅-fmerge-constants,-fmerge-all-constants)
  3. 没有
  4. 不确定