Correctly perform dynamic cast - c++

In Setting a variable in a child class, I was trying to figure out how to correctly derive variables in polymorphic classes. After some help, I found out that I needed to use a dynamic_cast on a pointer to correctly access the information I need. I am having some trouble with this.
This is the function I am currently working on.
void translateLines(Parser parser, Code code)
{
while(parser.hasMoreCommands())
{
vector<Command>::const_iterator it = parser.currentCommand();
if(it->commandType() == "A")
{
//SubType* item = dynamic_cast<SubType*>(*the_iterator);
A_COMMAND* a_command = dynamic_cast<A_COMMAND*>(*it); //line that is throwing the error
//string symbol = a_command->get_symbol();
//cout << "symbol: " << symbol << endl;
//perform binary conversion
}
/*else if(command.commandType() == "C")
{
string dest = command.get_dest();
}*/
//shouldn't be any L commands in symbol-less version
else
{
std::cout << "unexpected command value \n";
}
parser.advance();
}
}
This is my Parser.h, which has the relevant information regarding the iterator for the vector.
#include "Command.h"
#include <vector>
class Parser {
private:
std::vector<Command> commands;
std::vector<Command>::const_iterator command_it = commands.begin();
public:
Parser(std::vector<std::string>);
bool hasMoreCommands() //are there more commands in the input?
{
if(command_it != commands.end())
return true;
else
return false;
}
void advance(){std::next(command_it);} //move to next command, should only work if hasMoreCommands returns false}
std::vector<Command>::const_iterator currentCommand(){return command_it;}
std::vector<std::string> translateCommands(); //convert commands into binary strings
};
Here is the error I am receiving:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -o Assembler.o "..\\Assembler.cpp"
..\Assembler.cpp: In function 'void translateLines(Parser, Code)':
..\Assembler.cpp:32:55: error: cannot dynamic_cast 'it.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator*<Command*, std::vector<Command> >()' (of type 'class Command') to type 'class A_COMMAND*' (source is not a pointer)
A_COMMAND* a_command = dynamic_cast<A_COMMAND*>(*it);
^
Any clue what's wrong here?
EDIT: So I see now that I can't use a vector of Commands, rather I need pointers to the commands. I already have changed Parser.h to handle vector<Command*> rather than vector<Command>. For the input I tried something like this:
A_COMMAND command();
commands.push_back(&command);
But this isn't quite working for me, as the vector is expecting pointers and not references. What would be the easiest way to create a pointer to the memory and push it into the vector?

You have a vector of Commands. You cannot cast a Command to an A_COMMAND*. It's important to note that a vector<Command> cannot possibly contain a A_COMMAND. If you want to do runtime polymorphism in C++, you have to use pointers or references. In this case your Parser::commands would need to be a std::vector<Command*> (or some type of smart pointer like std::vector<std::shared_ptr<Command>>).
Take for example this code:
std::vector<Command> commands;
A_COMMAND a_command;
commands.push_back(a_command);
commands does not contain an A_COMMAND object. It contains a Command object that is a copy of a_command. It more-or-less equivilant of this:
std::vector<Command> commands;
A_COMMAND a_command;
Command temp(a_command);
commands.push_back(temp);
Remember, in C++ a variable is an object, not a reference to an object like in some other languages (Java or C# for instance). Objects will never change type, but you can have a reference or pointer of one type that points to an object of a derived type:
std::vector<Command*> commands;
A_COMMAND a_command;
commands.push_back(&a_command);
In this case commands[0] is a Command*, but it points to an A_COMMAND object.
RE your edit:
You are adding a pointer. &some_variable returns a pointer to some_variable, BUT you should absolutely never, ever do something like that. As soon as command goes out of scope, it will be destroyed and any access to it will result in undefined behavior. You will need to use dynamic memory allocation with new. It would probably be best to use a smart pointer class like std::shared_ptr<Command> to hold your dynamically allocated objects so you don't have to worry about deleteing them later.
If you use raw pointers then something like this will work:
A_COMMAND* command = new A_COMMAND;
commands.push_back(command);
If you go with that approach, you'll need to delete all of your commands when you're done with them (probably Parser's destructor):
for(Command* command : commands) {
delete command;
}
It would be better to use std::shared_ptrs though. Declare commands as std::vector<std::shared_ptr<Command>> commands;, then:
std::shared_ptr<A_COMMAND> command = std::make_shared<A_COMMAND>();
commands.push_back(command);
Then your objects will all get automatically deleteed when the last shared_ptr to them goes out of scope. If you use smart pointers you'll need to cast them slightly differently though. Look into std::dynamic_pointer_cast.

The real question is why use dynamic_cast at all.
This is a job for virtual methods.
If another class is derived, then your dynamic_cast will also need updating, with a virtual method you do not need to be concerned what the derived class is, only that it overrides the virtual method, which can be forced by using an interface class for the base (pure virtual methods, no state). This sounds like an application for the strategy pattern. https://en.wikipedia.org/wiki/Strategy_pattern.

try (it) instead of (*it)
the iterator should be a pointer to the object allready so you need to omit the * as this would result in the actual data not the reference

Related

Downcasting trouble

This is my first experience with downcasting in C++ and I just can't understand the problem.
AInstruction and CInstruction inherit from AssemblerInstruction.
Parser takes the info in its ctor and creates one of those derived instruction types for its mInstruction member (accessed by getInstruction). In the program, a method of the base AssemblerInstruction class is used, for happy polymorphism.
But when I want to test that the Parser has created the correct instruction, I need to query the derived instruction members, which means I need to downcast parser.getInstruction() to an AInstruction or CInstruction.
As far as I can tell this needs to be done using a bunch of pointers and references. This is how I can get the code to compile:
TEST(ParserA, parsesBuiltInConstants)
{
AssemblerInstruction inst = Parser("#R3", 0).getInstruction();
EXPECT_EQ(inst.getInstructionType(), AssemblerInstruction::InstructionType::A);
AssemblerInstruction* i = &(inst);
AInstruction* a = dynamic_cast<AInstruction*>(i);
EXPECT_EQ(a->getLine(), "R3");
}
Running this gives this error:
unknown file: error: SEH exception with code 0xc0000005 thrown in the test body.
And stepping through the code, when the debugger is on the final line of the function, a is pointing to
0x00000000 <NULL>.
I imagine this is an instance where I don't have a full enough understanding of C++, meaning that I could be making a n00b mistake. Or maybe it's some bigger crazy problem. Help?
Update
I've been able to make this work by making mInstruction into a (dumb) pointer:
// in parser, when parsing
mInstructionPtr = new AInstruction(assemblyCode.substr(1), lineNumber);
// elsewhere in AssemblerInstruction.cpp
AssemblerInstruction* AssemblyParser::getInstructionPtr() { return mInstructionPtr; }
TEST(ParserA, parsesBuiltInConstants)
{
auto ptr = Parser("#R3", 0).getInstructionPtr();
AInstruction* a = dynamic_cast<AInstruction*>(ptr);
EXPECT_EQ(a->getLine(), "R3");
}
However I have trouble implementing it with a unique_ptr:
(I'm aware that mInstruction (non-pointer) is redundant, as are two types of pointers. I'll get rid of it later when I clean all this up)
class AssemblyParser
{
public:
AssemblyParser(std::string assemblyCode, unsigned int lineNumber);
AssemblerInstruction getInstruction();
std::unique_ptr<AssemblerInstruction> getUniqueInstructionPtr();
AssemblerInstruction* getInstructionPtr();
private:
AssemblerInstruction mInstruction;
std::unique_ptr<AssemblerInstruction> mUniqueInstructionPtr;
AssemblerInstruction* mInstructionPtr;
};
// in AssemblyParser.cpp
// in parser as in example above. this works fine.
mUniqueInstructionPtr = make_unique<AInstruction>(assemblyCode.substr(1), lineNumber);
// this doesn't compile!!!
unique_ptr<AssemblerInstruction> AssemblyParser::getUniqueInstructionPtr()
{
return mUniqueInstructionPtr;
}
In getUniqueInstructionPtr, there is a squiggle under mUniqueInstructionPtr with this error:
'std::unique_ptr<AssemblerInstruction,std::default_delete>::unique_ptr(const std::unique_ptr<AssemblerInstruction,std::default_delete> &)': attempting to reference a deleted function
What!? I haven't declared any functions as deleted or defaulted!
You can not downcast an object to something which doesn't match it's dynamic type. In your code,
AssemblerInstruction inst = Parser("#R3", 0).getInstruction();
inst has a fixed type, which is AssemblerInstruction. Downcasting it to AInstruction leads to undefined behavior - manifested as crash - because that is not what it is.
If you want your getInstruction to return a dynamically-typed object, it has to return a [smart] pointer to base class, while constructing an object of derived class. Something like that (pseudo code):
std::unique_ptr<AssemblerInstruction> getInstruction(...) {
return std::make_unique<AInstruction>(...);
}
Also, if you see yourself in need of downcasting object based on a value of a class, you are doing something wrong, as you are trying to home-brew polymorphism. Most of the times it does indicate a design flaw, and should instead be done using built-in C++ polymorphic support - namely, virtual functions.

how to correctly pass data structures between custom llvm passes

I have a Function pass, called firstPass, which does some analysis and populates:
A a;
where
typedef std::map< std::string, B* > A;
class firstPass : public FunctionPass {
A a;
}
typedef std::vector< C* > D;
class B {
D d;
}
class C {
// some class packing information about basic blocks;
}
Hence I have a map of vectors traversed by std::string.
I wrote associated destructors for these classes. This pass works successfully on its own.
I have another Function pass, called secondPass, needing this structure of type A to make some transformations. I used
bool secondPass::doInitialization(Module &M) {
errs() << "now running secondPass\n";
a = getAnalysis<firstPass>().getA();
return false;
}
void secondPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<firstPass>();
AU.setPreservesAll();
}
The whole code compiles fine, but I get a segmentation fault when printing this structure at the end of my first pass only if I call my second pass (since B* is null).
To be clear:
opt -load ./libCustomLLVMPasses.so -passA < someCode.bc
prints in doFinalization() and exits successfully
opt -load ./libCustomLLVMPasses.so -passA -passB < someCode.bc
gives a segmentation fault.
How should I wrap this data structure and pass it to the second pass without issues? I tried std::unique_ptr instead of raw ones but I couldn't make it work. I'm not sure if this is the correct approach anyway, so any help will be appreciated.
EDIT:
I solved the problem of seg. fault. It was basically me calling getAnalysis in doInitialization(). I wrote a ModulePass to combine my firstPass and secondPass whose runOnModule is shown below.
bool MPass::runOnModule(Module &M) {
for(Function& F : M) {
errs() << "F: " << F.getName() << "\n";
if(!F.getName().equals("main") && !F.isDeclaration())
getAnalysis<firstPass>(F);
}
StringRef main = StringRef("main");
A& a = getAnalysis<firstPass>(*(M.getFunction(main))).getA();
return false;
}
This also gave me to control the order of the functions processed.
Now I can get the output of a pass but cannot use it as an input to another pass. I think this shows that the passes in llvm are self-contained.
I'm not going to comment on the quality of the data structures based on their C++ merit (it's hard to comment on that just by this minimal example).
Moreover, I wouldn't use the doInitialization method, if the actual initialization is that simple, but this is a side comment too. (The doc does not mention anything explicitly about it, but if it is ran once per Module while the runOn method is ran on every Function of that module, it might be an issue).
I suspect that the main issue seems to stem from the fact A a in your firstPass is bound to the lifetime of the pass object, which is over once the pass is done. The simplest change would be to allocate that object on the heap (e.g. new) and return a pointer to it when calling getAnalysis<firstPass>().getA();.
Please note that using this approach might require manual cleanup if you decide to use a raw pointer.

How to store inside a queue a unique_ptr of object which is located inside a vector

So I am building a simulator in order to simulate some load balancing algorithms. I have created 2 vectors of Cores and Dispatchers as shown below:
std::vector<std::unique_ptr<Dispatcher> > vDisp;
std::vector<std::unique_ptr<Core> > vCore;
The class dispatcher has a queue for the cores in order to assign to them the jobs.
std::queue<Core> disp_core_queue;
Plus I have some functions in order to handle this queue:
void add_core_q(Core& p){ disp_core_queue.push(p); }
Core get_core_q(){ return disp_core_queue.front(); }
When the program initializes I populate the cores and disps like this:
for (auto i=0; i<dispNumb; ++i)
{
vDisp.push_back(std::unique_ptr<Dispatcher> (new Dispatcher));
std::cout<<"Disp n."<<i<<" Created"<<std::endl;
}
My problem is that I cannot get a Core from the vector and store it inside a Dispatcher's queue. I have tried many ways but it seems C++ punishes me for various reasons. My last try was this one from inside the Dispatcher:
int kore = random_core();
this->add_core_q(vCore.at(kore));
Which gave this error in compile time:
error: no matching function for call to 'Dispatcher::add_core_q(_gnu_cxx::__alloc_traits > >::value_type&) '
candidate is:
void Dispatcher::add_core_q(Core&)
no known conversion for argument 1 from '__gnu_cxx::__alloc_traits > >::value_type {aka std::unique_ptr}' to 'Core&'
If anyone could give me a hint I would greatly appreciate it. Thanks in advance.
The function signature for add_core_q is taking Core&.
You are passing in a std::unique_ptr.
Your Core objects are stored inside unique_ptr's yet your add_core_q method requires a Core reference.
You could get the raw pointer from the unique_ptr and dereference it which would allow you to do this:
add_core_q(*(vCore[0]));
However you're also going to have a problem with your get_core_q method since it returns a copy of the Core object rather than a reference to the Core stored in the unique_ptr.
Personally I'd just pass around pointers rather than dereferencing things. So you'd change your add_core_q method to accept a raw pointer:
void add_core_q(Core* p){ disp_core_queue.push(p); }
Which you would use like this:
add_core_q(vCore[0].get());
You'd also have to change your queue to store pointers rather than the objects themselves:
std::queue<Core*> disp_core_queue;
And you'll need to change the return type of your get method to a pointer.
Core* get_core_q(){ return disp_core_queue.front(); }
Though if you're more comfortable with references you could return a reference instead:
Core& get_core_q(){ return *(disp_core_queue.front()); }

How to return a reference to a new object without memory leaks? c++

I'm writing macros for debugging system
I have an overloaded chained operator <<(MessageAssembler& target,message_type msg)
(message_type) is a template parameter for the operator
It adds msg to target's inner variable of type QTextStream.
The operator +=(MessageAssembler& result) of MessageAssembler passes result's stream to function which processes it based on parameters of result.
I want to do something like this:
#define FATAL(facility) NLog::assembler+=MessageAssembler(Log::fatal_sev,facility)<< __FILE__<<":"<<__LINE__
(NLog::assembler is a static variable of type MessageAssembler)
It should determine output's facility, allow a user to add its own message to output by using
FATAL(some_facility)<<"custom message"<<ObjectWhichCanBePassedToQTextStream()<<AnotherObject();
But MessageAssembler(Log::fatal_sev,facility) produces a reference to temporary error.
This
MessageAssembler& MessageAssembler::get_instance(Log::Severity _msg_sev,Log::Facility _msg_fac)
{
MessageAssembler tmp(_msg_sev,_msg_fac);
return tmp;
}
will return a reference to a non-existing object;
This
MessageAssembler& MessageAssembler::get_instance(Log::Severity _msg_sev,Log::Facility _msg_fac)
{
return new MessageAssembler tmp(_msg_sev,_msg_fac);
}
will cause a memory leak
This
QScopedPointer<MessageAssembler> MessageAssembler::get_instance(Log::Severity _msg_sev,Log::Facility _msg_fac)
{
return QScopedPointer<MessageAssembler>(new MessageAssembler tmp(_msg_sev,_msg_fac));
}
will not work because QScopedPointer can't be passed by value
I'm not sure if storing second static variable MessageAssembler chain_starter; is thread-safe.
I have not only FATAL macro, so the program won't be always terminated after the call.
How can i return a reference to a new MessageAssembler?
EDIT: My problem was solved by installing a third-party library for smart pointer, namely, yasper. The general solution is proposed by πάντα ῥεῖ.
The most concise answer is:
Don't do it using raw pointers! Use the c++ smart pointer features instead.
The most straightforward implementation seems to be, creating a std::unique_ptr<MessageAssembler> instance and return this one. The calling client will receive ownership of the created instance and it will be deleted automatically, as soon that reference goes out of scope.

Using functions from classes

I am learning C++ and very new at using classes, and I am getting very confused in trying to use them. I am trying to convert my existing code (which used structs) so that it uses classes - so while I know what I am trying to do I don't know if I'm doing it correctly.
I was told that when using functions from the class, I first need to instantiate an object of the class. So what I have tried (a snippet) in my main function is:
int main()// line 1
{
string message_fr_client = "test"; //line2
msgInfo message_processed; //line 3
message_processed.incMsgClass(message_fr_client); //line 4
if (!message_processed.priority_check(qos_levels, message_processed)) //line 5
cout << "failure: priority level out of bounds\n"; //line 6
return 0; //line 7
}
Could you help me clarify if my following assumptions are correct? The compiler is not showing any error and so I don't know if it is error-free, or if there are ones lurking beneath.
At line 4, is the function incMsgClass being performed on the string message_fr_client and returning the resultant (and modified) message_processed?
At line 5, the function priority_check is being performed on the message_processed and returning a boolean?
In my class definition, I have a function getPath that is meant to modify the value of nodePath - is it just a matter of using message_processed.getPath(/*arguments*/)?
I haven't included the body of the functions because I know they work - I would just like to find out how the class functions interact. Please let me know if I can be clearer - just trying to clear up some confusion here.
Here is my class:
#ifndef clientMsgHandling_H
#define clientMsgHandling_H
#include <list>
#include <map>
#include <queue>
class msgInfo
{
public:
msgInfo();
msgInfo(int, int, int, std::string, std::list<int>);
/*classifying message*/
msgInfo incMsgClass(std::string original_msg);
/*message error checks*/
bool priority_check(int syst_priority, msgInfo msg); //check that message is within qos levels
bool route_check(std::map<std::pair<int, int>, int> route_table, msgInfo msg); //check that route exists
void getPath(msgInfo msg, std::map<std::pair<int, int>, int> route_info, int max_hop);
private:
int source_id;
int dest_id;
int priority;
std::string payload;
std::list<int> nodePath;
};
#endif
While it may compile (and even run), there are a few oddities with the code as shown:-
First off, class methods know which object they are operating on - so your priority_check and route_check methods probably don't need msgInfo as a parameter.,
for example, your old non-class function might be like this
bool priority_check(int p, msgInfo msg)
{
return msg.priority < p;
}
But the new one should look like this:
bool msgInfo::priority_check(int p)
{
return priority < p;
}
Also, incMsgClass is a bit odd, as it's a non-static class method that returns a msgInfo object. It's difficult to tell without understanding what it's supposed to do, but it seems possible that this function should actually be a constructor, rather than a regular method.
One other thing is that you're currently passing a msgInfo by value to those methods. So if the method needed to modify the passed msgInfo, it would not have any effect. It's generally better to pass objects by reference or const reference to other methods. So, back to the previous non-method example, it should really be this.
bool priority_check(int p, const msgInfo &msg)
...
But, as I said, you probably don't need the msgInfo parameters anyway.
At line 4, is the function incMsgClass being performed on the string message_fr_client
Yes
and returning the resultant (and modified) message_processed?
Whatever it's returning, you're ignoring the return value. It can modify the object itself, yes, because the function is not const.
At line 5, the function priority_check is being performed on the message_processed and returning a boolean?
Yes
In my class definition, I have a function getPath that is meant to modify the value of nodePath - is it just a matter of using message_processed.getPath(/arguments/)?
If a member function is intended to modify one of the class members, it's just a matter of not marking that function const
Hard to tell without implementation-details, but here we go:
I. You are passing a std::string as value (C++ is call-by-value by default), so you get a copy of the std::string in your method. If you want to work on the object you passed and manipulate it, use a reference on the object, like
msgInfo incMsgClass(std::string& original_msg); // notice the ampersand
then you can change your signature to
void incMsgClass(std::string& original_msg);
as you don't need to return the std::string you passed.
II. Yes, at least according to your signature
III. Can see a node_path only as a member.
For all your questions, see C++-FAQ.
Your basic assumptions are correct.
message_processed.incMsgClass(message_fr_client); //line 4
This line is not correct. The function you call returns msgInfo which is simply dropped. You should assign it to something. But it is not as it is usually done. You should make it a constructor of msgInfo, like
class msgInfo
{
public:
msgInfo(std::string original_msg);
...
}
Then you could call it like this
msgInfo message_processed(message_fr_client);
That line would create a msgInfo that is already properly initialized.
There is another pattern for creating class instances - static creating function. In your case you could mark incMsgClass static and then call it like
msgInfo message_processed = msgInfo.incMsgClass(message_fr_client);
I seriously doubt you need this pattern here, so I'd advise to move to constructor.
As of other functions, I see no problems there. Just note that all member functions not marked as const can modify the object they are called on. So, you don't need to pass this object explicitly. For functions a pointer to the object they are called on is available by name this. Also the functions can access all class variables as if these variables are global for normal (non-member) functions.