如何在 GCC 中将重复或相乘的字符串文字合并为一个 [重复]
Posted
技术标签:
【中文标题】如何在 GCC 中将重复或相乘的字符串文字合并为一个 [重复]【英文标题】:how to merge duplicated or multiplicated string literals into one in GCC [duplicate] 【发布时间】:2015-08-13 00:28:39 【问题描述】:我得到了相乘的字符串字面量
char* a1 = "apalaxia";
char* t = "apalaxia";
char* zzzz = "apalaxia";
跨越几个编译单元/ .o 文件
我强烈需要将它们全部合并到一个运行时 地址(因此所有这些都是一个 char* 值)
如何在 GCC(在 c++ 模式下)中做到这一点?我试过 -fmerge-constants 和 -fmerge-all-constants 但 id 不合并
【问题讨论】:
请选择一种语言。可能的答案可能取决于语言。 C 和 C++ 是不同的语言! c 和 c++,我写 c 但在 c++ 模式下编译,所以这里可能更多 c++ 也许最好解释一下为什么希望它们合并到一个运行时地址下。你想实现什么或者背后的逻辑是什么? @Olaf:这个前提经不起实验。它与 C 的工作方式相同。如果您感兴趣,-fmerge-constants
标志会导致将字符串放置在设置了 Merge 和 Strings 标志的rodata 部分中,这允许链接器将它们组合起来。 (当然,这高度依赖于链接器,这可能是它不适用于 OP 的原因。)
@olaf:尽管如此,这是一个合法的要求,并且它具有可移植和可维护的解决方案。 OP 不要求解决方案是 -fmerge-constants
标志,因此无需纠结于该特定想法的不足之处。提出一些可行的建议会更有用。
【参考方案1】:
-fmerge-constants 和 -fmerge-all-constants 都不能保证字符串文字会被合并。两者都表示他们“尝试合并相同的常量”,但不保证他们会这样做。
此外,C++ 标准的第 2.13.5 节规定“是否所有字符串文字都是不同的(即,存储在不重叠的对象中)以及字符串文字的连续求值是否产生相同或不同的对象是未指定的。”
所以不幸的是,我认为没有明确声明每个副本并将其导出到使用它的翻译单元的情况下,没有办法获得保证的单一位置。
【讨论】:
该语言要求变量具有不同的地址,但它不能保证它们指向什么。如果您有const char* a="foo", *b="foo"; then
a` 和b
(它们是指针)将是不同的内存位置,但它们很可能具有相同的值(通常会)。 -fmerge-all-constants
"考虑例如常量初始化数组或整数或浮点类型的初始化常量变量";这些是可能违反标准的情况。
rici:我一直假设只有在从未比较过 a 和 b 指针的值的情况下才会合并它们,因为第 1.8 节要求所有对象(满足某些条件)具有不同的地址,但如果行为“好像”它们位于不同的地址,则允许它们合并,如果代码(例如评估(a == b)。但在进一步阅读时,看起来字符串文字对象在 2.13.5 中有特殊规则,这使得它无关紧要。我已经相应地编辑了答案。
真可悲,也许有人知道其他编译器呢?【参考方案2】:
有什么问题
const char text[] = "apalaxia";
const char *t = text;
...
C 和 C++ 标准都不保证合并字符串文字。如果您需要相同的地址,则无法使用单个定义。
请注意,如果指针稍后可能指向非const
,则必须将它们声明为char *
,但分配const
指针可能会遇到麻烦。
【讨论】:
很多错误我不想记住共享或创建中间名称 - 我只需要合并字符串....我知道标准不保证但也许 GCC 有这个可用的选项?正如我所说,我尝试了两个选项但它不起作用,我也尝试了 const char* 也没有合并 我不记得文字并且不希望代码变大,我只想合并字符串 - 我需要向您澄清多少次?以上是关于如何在 GCC 中将重复或相乘的字符串文字合并为一个 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Sqlite 中将两列合二为一,同时获取外键的底层值?