唯一综合名称 < >我想用C++中的唯一确定名称生成各种数据类型。例如: struct struct_int_double { int mem0; double mem1; };
目前,我的编译器使用计数器合成名称,这意味着在不同的转换单元中编译相同的数据类型时,名称不一致 以下是不起作用的:唯一综合名称 < >我想用C++中的唯一确定名称生成各种数据类型。例如: struct struct_int_double { int mem0; double mem1; };,c++,compiler-theory,C++,Compiler Theory,目前,我的编译器使用计数器合成名称,这意味着在不同的转换单元中编译相同的数据类型时,名称不一致 以下是不起作用的: 使用ABI mangled_name函数。因为它已经依赖于具有唯一名称的结构。通过假装struct是匿名的,是否可以在符合C++11的ABI中工作 模板例如struct2,因为模板不能与递归类型一起工作 彻底的破坏。因为它给出的名称太长(数百个字符!) 除了全局注册(YUK!)之外,我唯一能想到的就是先创建一个唯一的长名称,然后使用摘要或哈希函数来缩短它(希望没有冲突) 实际问题:
template<class T>
typedef pair<list<T>*, T> list;
有几个解决办法。对于这个特殊的问题,您可以使用Barton-Nackman技巧的变体,但它不能推广
有一个一般的解决方案,首先由Gabrielle des Rois展示,使用一个带有递归递归的模板,然后用一个部分专门化来关闭它。但这是极难生成的,即使我能想出如何生成,也可能无法读取
正确地处理变体也有另一个问题,但这并不是直接相关的(更糟糕的是,对使用可构造类型声明联合的愚蠢限制)因此,我的编译器只使用普通的C类型。无论如何,它必须处理多态性:写一个原因是绕过C++模板系统包括模板的问题。这就导致了命名问题。我不太理解您的问题
template<typename T>
struct SListItem
{
SListItem* m_prev;
SListItem* m_next;
T m_value;
};
int main()
{
SListItem<int> sListItem;
}
模板
结构SListItem
{
SListItem*m_prev;
SListItem*m_下一步;
T m_值;
};
int main()
{
SListItem SListItem;
}
你真的需要这些名字才能同意吗?只需在不同的翻译单元和sid
(struct,int,double)或si32f64
(struct,32位整数,64位浮点)或任何内容,而不是生成struct\u int\u double
。这样的名称有一个优点,即它们仍然可以直接解析(这似乎对调试非常重要)
编辑
还有一些想法:
- 模板:我看不出生成模板代码来解决这个问题有什么真正的好处,即使这是可能的。如果您担心链接器中的符号名长度限制,模板帮不了您,因为链接器没有模板概念:它所看到的任何符号都是由C++编译器生成的模板结构的变形形式,并且与FeliX编译器直接生成的冗长名称完全相同。
- 在FeliX代码中命名的任何类型都应该被保留并直接(或几乎直接)在生成的C++代码中使用。我认为在felix代码中使用的匿名类型的复杂性上存在实际(软)可读性/可维护性约束,这是您需要为其生成名称的唯一约束。我假设您的“变体”是有区别的联合体,因此每个组成部分都必须在felix代码中定义一个名称(标记),并且这些名称也可以保留。(我在评论中提到了这一点,但由于我正在编辑我的答案,我不妨将其包括在内)
- 减少损坏的名称长度:通过哈希函数运行一个长的损坏名称听起来是最简单的方法,只要使用一个好的哈希函数并在您的哈希名称中保留足够的位,冲突的可能性应该是可以接受的(用于编码散列名称的字母表有37个字符,因此完整的160位sha1散列可以用大约31个字符编写)。散列函数的概念意味着您将无法直接从散列名称返回到原始名称,但您可能永远不需要这样做。我想,您可以在编译过程中转储一个辅助名称映射表(或者从C结构定义中重新生成名称,如果可以的话)。或者,如果您仍然不喜欢散列函数,您可能会定义一个合理紧凑的位级编码(然后将其写入37个字符的标识符字母表),甚至在位级编码上运行一些通用压缩算法。如果你有足够的felix代码进行分析,你甚至可以预先生成一个固定的压缩字典。这就是stark ravi
template<typename T> struct SListItem { SListItem* m_prev; SListItem* m_next; T m_value; }; int main() { SListItem<int> sListItem; }