Scorbutics
Scorbutics

Reputation: 3

How can a const pointer refering to mutable data can be 'converted back' to non-const pointer?

I'm refactoring a compiler front-end, and facing a problem of const variable, which are non reversible to their non-const counterpart.

Context is the following : I have an abstract syntax tree (AST) and a symbol table which contains symbols, and I want to compute types of the ast nodes and symbols in the symbol table. I will refer the type computation part as 'Subsystem'.

Constraints are the following :

Here is a (really simplified) version of what I am talking about :

#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;
}

Which results in the following compilation error under 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;
      |     ~~~~~~~~~~~~~~^~~

Problem is : as Symbol table and AST are passed "const" to the Subsystem, it is now impossible to get a const pointer from the returned TypeSymbol 's' value.

How can I get back to a non-const pointer in this context ? I thought about using const_cast, but it usually implies a design flaw, isn't it ?

Upvotes: 0

Views: 169

Answers (1)

R Sahu
R Sahu

Reputation: 206717

Use of const_cast is an option in your case.

*const_cast<Symbol*>(typeSymbol.s) = 1;

but remember that it can be dangerous some times.

If the original object was created as a const object, you run the risk of undefined behavior.

Upvotes: 1

Related Questions