【发布时间】:2020-03-13 22:40:12
【问题描述】:
我正在重构一个编译器前端,并面临 const 变量的问题,该变量对于它们的非 const 对应项是不可逆的。
上下文如下:我有一个抽象语法树 (AST) 和一个包含符号的符号表,我想计算符号表中 ast 节点和符号的类型。 我将类型计算部分称为“子系统”。
约束如下:
- 我的 AST 是一个复杂的结构,所以我想避免每次都遍历所有节点。
- 子系统是按照功能范式构建的,所以它不会直接改变任何东西(既不是 AST 也不是符号表),而只是使用符号表计算一个类型并最终计算一个符号。它的参数是当前需要计算的 AST 节点和符号表。
- 当子系统计算完成后,我想将返回的符号引用为非常量指针。
这是我所说的(非常简化的)版本:
#include <string>
#include <map>
// For readability / understandability only
using Type = int;
using Symbol = int;
struct TypeSymbol {
Type t;
const Symbol* s;
};
TypeSymbol ComputeTypeSymbolInSubsystem(const std::map<std::string, int>& data) {
return { 123, &data.at("bar") };
}
int main()
{
std::map<std::string, Symbol> symbols = { {"test", 0 } , { "foo", 51 }, { "bar", 63 }, {"", 2 } };
auto typeSymbol = ComputeTypeSymbolInSubsystem(symbols);
// Obvious compilation error, even if "s" is still refering to a mutable memory zone (the symbols variable)
*typeSymbol.s = 1;
return 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-pointer-to-non-const-data 与 nonconst-pointer-to-const-data 之间的区别吗?您正在处理后者,这就是您的代码无法编译的原因。您正在尝试通过指向常量数据的指针来修改数据,这意味着该指针不能用于写入。如果您知道指向的内存是可写的,那么是的,您可以
const_cast指针以允许写入数据。否则,您需要重新考虑使用const -
@RemyLebeau 是的,我愿意,编译失败只是显示我实际系统设计问题的超简化版本的一种方式。我知道错误,但不是正确的解决方案,除了这个 const_cast。
标签: c++ architecture constants