字符串文字的 C 优化 [英] C optimisation of string literals

查看:28
本文介绍了字符串文字的 C 优化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚在 gdb 中检查了以下内容:

char *a[] = {一"、二"、三"、四"};char *b[] = {一"、二"、三"、四"};char *c[] = {二"、三"、四"、五"};char *d[] = {一"、三"、四"、六"};

...我得到以下信息:

(gdb) p a$17 = {0x80961a4一"、0x80961a8二"、0x80961ac三"、0x80961b2四"}(gdb) p b$18 = {0x80961a4一"、0x80961a8二"、0x80961ac三"、0x80961b2四"}(gdb) pc$19 = {0x80961a8二"、0x80961ac三"、0x80961b2四"、0x80961b7五"}(gdb) p d$20 = {0x80961a4一"、0x80961ac三"、0x80961b2四"、0x80961bc六"}

我真的很惊讶字符串指针对于等效单词是相同的.我原以为每个字符串都会在堆栈上分配自己的内存,而不管它是否与另一个数组中的字符串相同.

这是某种编译器优化的示例还是此类字符串声明的标准行为?

解决方案

它被称为字符串池化".它在 Microsoft 编译器中是可选的,但在 GCC 中不是.如果您在 MSVC 中关闭字符串池,那么不同数组中的相同"字符串将被复制,并具有不同的内存地址,因此会占用额外(不必要的)50 字节左右的静态数据.

v 4.0 之前的 gcc 有一个选项,-fwritable-strings 禁用字符串池.此选项的作用有两个:它允许覆盖字符串文字,并禁用字符串池化.所以,在你的代码中,设置这个标志会允许一些危险的代码

/* 覆盖 a 中的第一个字符串,使其读取为 'xne'.才不是 *//* 影响 b 或 d 中字符串 "one" 的实例 */*a[0] = 'x';

I've just been inspecting the following in gdb:

char *a[] = {"one","two","three","four"};
char *b[] = {"one","two","three","four"};
char *c[] = {"two","three","four","five"};
char *d[] = {"one","three","four","six"};

...and I get the following:

(gdb) p a
$17 = {0x80961a4 "one", 0x80961a8 "two", 0x80961ac "three", 0x80961b2 "four"}
(gdb) p b
$18 = {0x80961a4 "one", 0x80961a8 "two", 0x80961ac "three", 0x80961b2 "four"}
(gdb) p c
$19 = {0x80961a8 "two", 0x80961ac "three", 0x80961b2 "four", 0x80961b7 "five"}
(gdb) p d
$20 = {0x80961a4 "one", 0x80961ac "three", 0x80961b2 "four", 0x80961bc "six"}

I'm really surprised that the string pointers are the same for equivalent words. I would have thought each string would have been allocated its own memory on the stack regardless of whether it was the same as a string in another array.

Is this an example of some sort of compiler optimisation or is it standard behaviour for string declaration of this kind?

解决方案

It's called "string pooling". It's optional in Microsoft Compilers, but not in GCC. If you switch off string pooling in MSVC, then the "same" strings in the different arrays would be duplicated, and have different memory addresses, and so would take up an extra (unnecessary) 50 or so bytes of your static data.

EDIT: gcc prior to v 4.0 had an option, -fwritable-strings which disabled string pooling. The effect of this option was twofold: It allowed string literals to be overwritten, and disabled string pooling. So, in your code, setting this flag would allow the somewhat dangerous code

/* Overwrite the first string in a, so that it reads 'xne'.  Does not */ 
/* affect the instances of the string "one" in b or d */
*a[0] = 'x';

这篇关于字符串文字的 C 优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆