Đorđe Relić Đorđe Relić - 2 months ago 4x
C++ Question

Why do we use pointers for complex classes when defining union in parser file?

I'm working on a parser for RDDL and, as I've done it before, when I define union which contains types I use, I use pointers. E.g.

%union {
double d;
int i;
std::string *str;
std::vector<std::string> *vectorStr;

RDDLBlock *rddlBlock;
Domain *domain;
DefineType *defineType;
std::vector<DefineType*> *vectorDefineType;
DomainList *domainList;
std::vector<PvarDefinition*> *vectorPvarDefinition;
PvarDefinition *pVarDefinition;
CpfDefinition *cpfDefinition;
std::vector<CpfDefinition*> *vectorCpfDefinition;
PvarExpression *pVarExpression;
LogicalExpression *logicalExpression;
std::vector<LogicalExpression*> *vectorLogicalExpression;
LConstCaseList *lConstCaseList;
CaseDefine *caseDefine;
std::vector<CaseDefine*> *vectorCaseList;
Parameter *parameter;
ParameterList *parameterList;

ObjectDefine *objectDefine;
std::vector<ObjectDefine*> *objectsList;
PvariablesInstanceDefine* pvariablesInstanceDefine;
std::vector<PvariablesInstanceDefine*> *pvariablesInstanceList;

Instance *instance;
NonFluentBlock *nonFluentBlock;


This is the way I saw most people implement multiple token types in parsers. While searching for this answer on the web, all I saw are the examples and no explanation on why we have to use pointers. One of my tasks now is to 'clean pointers' where ever that is possible. So my question is, why do we (have to) use pointers in unions in this case?

EDIT: Added full list of types defined in union.


You don't have to use pointers. As you can see, neither double nor int are pointers.

As to "why do we use" part then, we should remember some properties of union.

  1. sizeof union_t must be at least as big as the biggest member. So you don't want union with a single word int and some 1KB class by value. And pointer almost always have fixed small size.

  2. In C++ world, many classes (for your example, std::string and std::vector) have non-trivial copy constructors and destructors. For such classes, it is unsafe to put them in union (standard forbids it, as far as I know, but some compilers allow).