我发现以下模式经常发生:
b->last = ngx_cpymem(b->last, "</pre><hr>", sizeof("</pre><hr>") - 1);
请注意,文字字符串使用了两次。提取物来自nginx源库。
编译器应该能够在编译单元中遇到这些文字时合并这些文字。
我的问题是:
这些问题很重要,因为它允许程序员在不损失效率的情况下进行冗长 - 即,考虑将大量静态数据模型硬连接到程序中(例如,某些低级使用的决策支持系统的规则)级别场景)。
修改
2分/澄清
上面的代码由公认的“主”程序员编写。这家伙一手写了nginx。
我没有问过文字硬编码的哪种可能机制更好。所以不要偏离主题。
修改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");
对于那些留在话题上的人,勇敢!
答案 0 :(得分:8)
请注意,对于sizeof("</pre><hr>")
的特定情况,几乎可以肯定字符串文字永远不会出现在输出文件中 - 整个sizeof
表达式可以在编译时计算为整数常量11 -time。
尽管如此,编译器合并相同的字符串文字仍然是一种非常常见的优化。
答案 1 :(得分:7)
我无法回答你的问题,但在这种情况下总是尝试使用const字符串(甚至#define会更好)。当你重构代码并改变一个文字的值而忘记了另一个时,问题就出现了(在你的例子中不太可能,因为它们彼此相邻,但我之前已经看过了)。
无论编译器能做什么的人工操作,人类仍然可以进行操作:)
答案 2 :(得分:4)
我会很不高兴看到这种模式 - 如果有什么有人更改一个文字而不改变其他?它应该被拉出来;做一个很小的命名常量。
假设你不能出于某种原因,或者只是为了实际回答这个问题:(至少,有趣的。)
我在C中创建了一个类似的程序并用GCC 4.4.3编译它,常量字符串只在生成的可执行文件中出现一次。
编辑:因为它可能是一个简单的测试,这是我用它测试的代码...
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
main(){
char *n = (char*)malloc(sizeof("teststring"));
memcpy((void*)n, "teststring", sizeof("teststring"));
printf("%s\n", n);
}
这是我用来检查字符串出现次数的命令......
strings a.out|grep teststring
但请尽可能考虑使用不易出错的编码实践。
答案 3 :(得分:4)
答案 4 :(得分:4)
我写了一个小样本代码并编译:
void func (void)
{
char ps1[128];
char ps2[128];
strcpy(ps1, "string_is_the_same");
strcpy(ps2, "string_is_the_same");
printf("", ps1, ps2);
}
作为汇编程序文件的结果,即使没有优化,也只有一个文字“string_is_the_same”的实例。但是,不确定是否将这些字符串重复放入不同的文件中 - &gt;不同的目标文件。