C++ 引用可变数据的常量指针怎么可能是';转换回';到非常量指针?

C++ 引用可变数据的常量指针怎么可能是';转换回';到非常量指针?,c++,architecture,constants,C++,Architecture,Constants,我正在重构一个编译器前端,并且面临一个常量变量的问题,这个变量对于它们的非常量对应项是不可逆的 上下文如下:我有一个抽象语法树(AST)和一个包含符号的符号表,我想计算符号表中AST节点和符号的类型。 我将把类型计算部分称为“子系统” 限制条件如下: 我的AST是一个复杂的结构,所以我希望避免每次可能的时候遍历所有节点 子系统是按照功能范式构建的,因此它不会直接改变任何东西(AST或符号表),而只会使用符号表计算一个类型并最终计算一个符号。其参数是必须计算类型的当前AST节点和符号表 当子系统

我正在重构一个编译器前端,并且面临一个常量变量的问题,这个变量对于它们的非常量对应项是不可逆的

上下文如下:我有一个抽象语法树(AST)和一个包含符号的符号表,我想计算符号表中AST节点和符号的类型。 我将把类型计算部分称为“子系统”

限制条件如下:

  • 我的AST是一个复杂的结构,所以我希望避免每次可能的时候遍历所有节点
  • 子系统是按照功能范式构建的,因此它不会直接改变任何东西(AST或符号表),而只会使用符号表计算一个类型并最终计算一个符号。其参数是必须计算类型的当前AST节点和符号表
  • 当子系统计算完成时,我希望将返回的符号作为非常量指针引用
下面是我所说内容的一个(真正简化的)版本:

#包括
#包括
//仅用于可读性/可理解性
使用Type=int;
使用符号=int;
结构类型符号{
t型;
常量符号*s;
};
TypeSymbol ComputeTypeSymbolSubSystem(常量标准::映射和数据){
返回{123,&data.at(“bar”)};
}
int main()
{
地图符号={{“test”,0},{“foo”,51},{“bar”,63},{”,“2};
自动类型符号=计算类型符号系统(符号);
//明显的编译错误,即使“s”仍然指向可变内存区域(symbols变量)
*typeSymbol.s=1;
返回0;
}
这导致gcc 9.2.0下的以下编译错误:

main.cpp: In function 'int main()':
main.cpp:25:19: error: assignment of read-only location '* typeSymbol.TypeSymbol::s'
   25 |     *typeSymbol.s = 1;
      |     ~~~~~~~~~~~~~~^~~
问题是:由于符号表和AST被传递给子系统“const”,现在不可能从返回的TypeSymbol的值中获取const指针


在此上下文中,如何返回到非常量指针?我曾考虑过使用const_cast,但它通常意味着设计缺陷,不是吗?

在您的情况下,使用
const_cast
是一种选择

*const_cast<Symbol*>(typeSymbol.s) = 1;
*const_cast(typeSymbol.s)=1;
但请记住,有时这可能很危险


如果原始对象被创建为
const
对象,您将面临未定义行为的风险。

const\u cast
并不意味着设计缺陷,而是将只读数据视为可变数据。您理解指向非ST数据的const指针与指向const数据的非ST指针之间的区别吗?您正在处理后者,这就是代码无法编译的原因。您试图通过指向常量数据的指针修改数据,这意味着该指针不能用于写入。如果您知道所指向的内存是可写的,那么您可以
const\u cast
指针以允许写入数据。否则,您需要重新考虑您对
const
@RemyLebeau的使用是的,编译失败只是一种显示我实际系统设计问题的超简化版本的方式。我知道错误,但不是正确的解决方案,除了这个常量。谢谢。实际上,我100%确信我的原始对象是可变的,因为只有我的类SymbolTable被允许构建Symbol(使用一个私有的友元构造函数)。我不是康斯特卡斯特的超级粉丝,但如果这是唯一可行的解决方案,我必须接受它@Scorbutics,另一个选项是从
s
--
Symbol*s的声明中删除
const
@R Sahu,不幸的是,如果我这样做,我还必须到处删除const,因为编译错误将变成:
main.cpp:In函数'TypeSymbol computetypesymbonsubsystem(const std::map&)':main.cpp:14:30:error:const-mapped_-type*{aka'const-int*}到'Symbol*{aka'int*}的转换无效[-fpermissive]14 |返回TypeSymbol{123,&data.at(“bar”)};| ^~~~~~~~~~~~~~~~~~~~~~~~~| |const-mapped_-type*{aka const-int*}
@Scorbutics如果您将
const
留在需要的地方,则在将指针分配给
s
时,您只需
const-cast
,而不是在通过
s
写入内存时
const-cast
,例如:
TypeSymbol computetypesymbolicansubsystem(const std::map&data){return{123,&const_cast(data.at(“bar”)}}
如果您计划通过
s
写入内存,则绝对不应该将
s
声明为指向
const
内存。但实际上,
computetypesymbolicansubsystem()
引用一个
常量映射
如果数据本来是可变的?因为在实践中,ComputeTypeSymbolNSUBSystem是一个多文件系统(大约10个文件)它总共有1000行左右的if代码。我想确保我不能修改任何东西,以保持一种功能性的做事方式,并避免有很多地方编辑符号表。在分配指针时强制转换也是一个好主意。我会考虑的!