What obvious thing am I overlooking in this failing C++ class instantiation? - c++

I'm writing code for an Arduino-based retirement countdown clock (a gift for a coworker), and have grouped some code into a simple class. This chunk of code gives me the error "error: 'rd' does not name a type" when I compile it in the current (1.6.7) Arduino IDE:
#include "RetirementDisplay.h"
RetirementDisplay* rd;
rd = new RetirementDisplay(&update_lcd);
Oddly, this code compiles without error:
#include "RetirementDisplay.h"
RetirementDisplay* rd = new RetirementDisplay(&update_lcd);
But then when I try to use a member function (like rd->add_screen()) of the newly created rd object, I get the same "rd does not define a type" error, which is completely illogical to me. My C++ is super rusty, though, so I assume there's probably something I'm overlooking here.
The update_lcd method is defined earlier in the same file, and does take two String arguments, so I don't think it's upset about that.
The contents of RetirementDisplay.h are similarly simple; it's just a linked list and a couple of convenience functions to bundle related functionality together while tracking what "screen" (just a couple of printf formats) should currently be active. Don't judge me on my sketchy naming convention; this was supposed to be a quick project. ;)
#ifndef RetirementDisplay_h
#define RetirementDisplay_h
#include "RetirementScreen.h"
class RetirementDisplay {
protected:
RetirementScreen* head;
RetirementScreen* current;
void (*updater)(String, String);
public:
RetirementDisplay( void(*)(String,String) );
void add_screen(RetirementScreen*);
void update();
void next();
void prev();
};
#endif

It looks like this line is intended to be an assignment statement:
rd = new RetirementDisplay(&update_lcd);
but statements must be inside functions, like this:
#include "RetirementDisplay.h"
void myfunction()
{
RetirementDisplay* rd;
rd = new RetirementDisplay(&update_lcd);
}
However, variable declarations can be outside functions, so that is why you don't get an error on this line:
RetirementDisplay* rd = new RetirementDisplay(&update_lcd);

Related

What're all the LLVM layers for?

I'm playing with LLVM 3.7 and wanted to use the new ORC stuff. But I've been going at this for a few hours now and still don't get what the each layer is for, when to use them, how to compose them or at the very least the minimum set of things I need in place.
Been through the Kaleidoscope tutorial but these don't explain what the constituent parts are, just says put this here and this here (plus the parsing etc distracts from the core LLVM bits). While that's great to get started it leaves a lot of gaps. There are lots of docs on various things in LLVM but there's so much its actually bordering on overwhelming. Stuff like http://llvm.org/releases/3.7.0/docs/ProgrammersManual.html but I can't find anything that explains how all the pieces fit together. Even more confusing there seems to be multiple APIs for doing the same thing, thinking of the MCJIT and the newer ORC API. I saw Lang Hames post explaining, a fair few things seem to have changed since the patch he posted in that link.
So for a specific question, how do all these layers fit together?
When I previously used LLVM I could link to C functions fairly easily, using the "How to use JIT" example as a base, I tried linking to an externed function extern "C" double doIt but end up with LLVM ERROR: Tried to execute an unknown external function: doIt.
Having a look at this ORC example it seems I need to configure where it searches for the symbols. But TBH while I'm still swinging at this, its largely guess work. Here's what I got:
#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "std.hpp"
using namespace llvm;
int main() {
InitializeNativeTarget();
LLVMContext Context;
// Create some module to put our function into it.
std::unique_ptr<Module> Owner = make_unique<Module>("test", Context);
Module *M = Owner.get();
// Create the add1 function entry and insert this entry into module M. The
// function will have a return type of "int" and take an argument of "int".
// The '0' terminates the list of argument types.
Function *Add1F = cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context), Type::getInt32Ty(Context), (Type *) 0));
// Add a basic block to the function. As before, it automatically inserts
// because of the last argument.
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", Add1F);
// Create a basic block builder with default parameters. The builder will
// automatically append instructions to the basic block `BB'.
IRBuilder<> builder(BB);
// Get pointers to the constant `1'.
Value *One = builder.getInt32(1);
// Get pointers to the integer argument of the add1 function...
assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg
Argument *ArgX = Add1F->arg_begin(); // Get the arg
ArgX->setName("AnArg"); // Give it a nice symbolic name for fun.
// Create the add instruction, inserting it into the end of BB.
Value *Add = builder.CreateAdd(One, ArgX);
// Create the return instruction and add it to the basic block
builder.CreateRet(Add);
// Now, function add1 is ready.
// Now we're going to create function `foo', which returns an int and takes no
// arguments.
Function *FooF = cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context), (Type *) 0));
// Add a basic block to the FooF function.
BB = BasicBlock::Create(Context, "EntryBlock", FooF);
// Tell the basic block builder to attach itself to the new basic block
builder.SetInsertPoint(BB);
// Get pointer to the constant `10'.
Value *Ten = builder.getInt32(10);
// Pass Ten to the call to Add1F
CallInst *Add1CallRes = builder.CreateCall(Add1F, Ten);
Add1CallRes->setTailCall(true);
// Create the return instruction and add it to the basic block.
builder.CreateRet(Add1CallRes);
std::vector<Type *> args;
args.push_back(Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), args, false);
Function *F = Function::Create(FT, Function::ExternalLinkage, "doIt", Owner.get());
// Now we create the JIT.
ExecutionEngine *EE = EngineBuilder(std::move(Owner)).create();
outs() << "We just constructed this LLVM module:\n\n" << *M;
outs() << "\n\nRunning foo: ";
outs().flush();
// Call the `foo' function with no arguments:
std::vector<GenericValue> noargs;
GenericValue gv = EE->runFunction(FooF, noargs);
auto ax = EE->runFunction(F, noargs);
// Import result of execution:
outs() << "Result: " << gv.IntVal << "\n";
outs() << "Result 2: " << ax.IntVal << "\n";
delete EE;
llvm_shutdown();
return 0;
}
doIt is declared in std.hpp.
Your question is very vague, but maybe I can help a bit. This code sample is a simple JIT built with Orc - it's well commented so it should be easy to follow.
Put simply, Orc builds on top of the same building blocks used by MCJIT (MC for compiling LLVM modules down to object files, RuntimeDyld for the dynamic linking at runtime), but provides more flexibility with its concept of layers. It can thus support things like "lazy" JIT compilation, which MCJIT doesn't support. This is important for the LLVM community because the "old JIT" that was removed not very long ago supported these things. Orc JIT lets us gain back these advanced JIT capabilities while still building on top of MC and thus not duplicating the code emission logic.
To get better answers, I suggest you ask more specific questions.

if statement in main function c++

Okay, probably a dumb question to you guys but I can't figure it out.
So I'm taking a c++ basics course in class and so far I'm struggling/crying.
I can't show you guys my code because I'm not allowed/there are consequences if I'm caught but I could probably give a example.
I'm using xcode. So when I compile, I get two errors below (image provided).
I searched for similar questions, but those seem too complex compared to what I'm doing. In addition, the only includes I have are iostream and string.
I know the problem occurs when I add an if statement in my main function. I know this because when I delete it, everything compiles as expected. Yet when I add it again to the main function, these errors occur.
So my question is, based on what I know, is it proper to add an if statements whenever in the main function?
Below is an example. I wrote the functions below and called above.
#include <iostream>
#include <string>
using namespace std;
// example functions that I just made up to explain the structure of my actual code.
//Don't bother trying to understand it. It's just to explain that
//I wrote my functions at the
// bottom and called it at the top.
int getNumberofWins(param1, param2);
string getTheName(int player1);
int executeCycle(string p1_name, string p2_name);
void stateWinner(string winner_name);
int main {
playerOne = getTheName(1);
playerTwo = getTheName(2);
r1 = executeCycle(playerOne, playerTwo);
r2= executeCycle(playerOne, playerTwo);
totalWin1 = getNumberOfWins(1, r1, r2);
totalWin2 = getNumberOfWins(2, r1, r2);
cout << totalWin1;
//This is the where I get the errors. When I delete the if statement,
//Everything compiles. When I add it, an error occurs.
if (totalWin1 == 2){
stateWinner(playerOne);
}
return 0;
}
string getTheName(int player1){
string playerOne;
string playerTwo;
if(player_number == 1){ code code code
}
}
int getNumberofWins (int param1, int param2){
code code code
}
int executeCycle(string p1_name, string p2_name){
code code code
}
void stateWinner(string winner_name){
if(!winner_name.empty()){
code code code
}
I hope it's fine if the code above isn't accurate. I think the point is that once I add my if statement to the main function, the two errors show up.
actually...now that I look at it, they both seem like similar errors. I just don't know why they both appear...
Sorry if this is an obvious answer or if it isn't clear.
The "announceWinner" function is not defined anywhere, ie there's no
void announceWinner () {
// code
}
anywhere. Either you haven't written it yet, or the file that contains it is not being compiled & linked with the main program.

c++ - Creating custom events at runtime

I'm creating a 2D RPG game engine in C++ with Allegro. I've reached the point in which i need to implement a scripting system. So, my poblem is this one:
I have a struct called Event. Inside this struct there is a function pointer, which points to the function that i want to execute when the event is fired. So, here's an example:
struct Event {
//...
void (*func)(Player*, void*);
//...
}
Now, to create an event i have this function:
Event* Events::register_event_source(int x, int y, std::string name, Player* player, void (*func)(Player*, void*));
So, to use it i just need to create a function with this signature:
void test_event(Player* p, void* data)
{
//Do something cool here
}
and then register an event source, giving the address to that function:
//...
Player* player = new Player(0, 0);
//...
Event* evt = Events::register_event_source(10, 10, "test event", player, &test_event);
//Eventually set some data for the event
evt->set_data(new std::string("Just some test data"));
In this way, when the player goes over the assigned spot (in this case x = 10, y = 10) the event will fire, executing any code in the test_event function.
Now, my question is: is it possible to do, or at least to get close to, this process at runtime?? ...i would need to create the function (in this case "test_event") at runtime, but i did some research, and i think what i understood is that it is not really possible to create functions at runtime.
So, which approach should i go for?? ...I know it is an abstract question...but i really don't know how to approach this problem.
Thanks in advice for any help! and sorry for my bad explaining abilities...English is not my language!
If I understand correctly what you are trying to express, you are writing a scripting engine that interprets some logics built at run-time into a string, and this should determine what to do on Player and data. If so, I can imagine you should have a function like
void InterpretScriptCode(Player* p, void* data, string const& code)
or something equivalent that interprets and execute the logics described in code on p and data.
Then, you can use std::bind and std::function to encapsulate a call to your scripting engine:
// Header <functional> needs to be included, and a proper "using namespace"
// directive must be present for bringing placeholders _1 and _2 into scope
std::function<void(Player*, void*)> fxn = std::bind(
&InterpretScriptCode,
_1,
_2,
"int x = 0; ... blah blah" // this should be your run-time generated script
);
And pass fxn in input to your register_event_source() function.
Btw, you might be interested in using Boost.Signals/Boost.Signals2 for realizing event registration/handling.
If you are not using C++11, you can use boost::bind and boost::function instead of std::bind and std::function.

How to pass a char* from C to CPP?

A little background:
I've got a library of C code that is part of larger system (all C). For this particular part of the C library a GUI has to be created which allows users to play around with the options. For the GUI I've chosen QT, since cross-platform support is desired.
I'm using Eclipse and MinGW as IDE and compiler (but I think the question is more language than compiler specific?).
With QT I've created a widget that holds a pointer to a struct implemented in C that contains pointers to several functions that perform the logic of the C library.
//QTWidget.cpp
extern "C" {
#include "c-src/CLogic.h"
//extern char* textHelper;
}
QTWidget::QTWidget(QWidget *parent)
{
//rtw is a struct that contains a function pointer to a member of QTWidget
this->rtw.displayText = &QTWidget::displayText;
this->clogic = CLogic_getInstance(&rtw);
}
//Public SLOT, connected to a button's clicked SIGNAL
void QTWidget::buttonClicked()
{
this->clogic->buttonClicked();
}
void QTWidget::displayText(char *text, int position)
{
//I've tried creating a QString from the char*, but this does not work at all.
//ui.textItem->setText(textHelper);
ui.textItem->setText(text);
}
When the user presses a button in the GUI, the method QTWidget::buttonClicked() is called, which tells the C library to do something. Note the the CLogic struct has a reference to the the QTWidget in the form of a struct RefToWidget which holds a function pointer.
//CLogic.c
static CLogic instance;
void CLogic_buttonClicked()
{
//I've tried several variants here, such as making a global
//char* textHelper = "Hello World";
//that is referenced by using the "extern" keyword in the CPP file above.
instance.rtw->displayText("Hello World", 1);
}
CLogic* CLogic_getInstance(RefToWidget *rtw)
{
instance.rtw = rtw;
instance.buttonClicked = &CLogic_buttonClicked();
}
When debugging this program, I find that all the function calls are executed as intended (when I press a button, the QT slot buttonClicked() is called, the CLogic_buttonClicked() is called, which calls the QTWidget::displayText() as planned, but in this last call the parameters are invalid. The char* text points to 0x1 and claims to be pointing to memory out of bounds, while the int position looks like some random number (uninitialized).
How do I pass this data from C to CPP?
EDIT #Luccas Matteis:
#ifdef __cplusplus
#include "QTWidget.h"
extern "C" {
#endif
struct RefToWidget{
#ifdef __cplusplus
void (QTWidget::*displayLine)(char* text, int lineNumber);
#else
void (*displayLine)(char* text, int lineNumber);
#endif
};
typedef struct RefToWidget RefToWidget;
#ifdef __cplusplus
}
#endif
As said above the function calls behave as expected, but the data is not passed "correctly" (even though that when I look at it, the code seems a bit... weird... ;))
Your problem is not passing the char * from C to C++ but calling a C++ function from C. I presume that CLogic.c is compiled as a C library? If not, can you rename it to CLogic.cpp or use a compiler switch to force it to be compiled as C++ even though it has a C file extension?
If you want a C++ GUI on a C library/system, you need to use proper Model-View-Controller logic. Here the C++ code is the View and the Controller while the C code is the Model (as best as I can tell from your description). You need to make it so you set and get data from the model but the model never calls the View or Controller as you are trying to do.
Think about what you are REALLY trying to do. If you just want to display a static string when the button is pressed, why go to the bother of calling into CLogic.c? If you want to display a string that depends upon the state of the CLogic instance then instead do something like:
void QTWidget::buttonClicked()
{
char *display_text = this->clogic->get_button_click_text();
ui.textItem->setText(display_text);
}
I guess the problem is that the structure holds a pointer to a member function. The member function probably expects the first parameter to be 'this' - the object it refers to. So, in fact what you are seeing in debug as text is the second parameter.
A 'solution' would probably be to do something like "instance.rtw->displayText(instance.rtw, "Hello World", 1)", but have no idea if it is portable etc.
Edit: Saying it explicitly: the 'solution' stated above is just to try and check if this is the problem. As the comments are saying this is a horrible hack that might not work even on the same compiler.
I don't think that you should call a C++ method from C. Normally you need to go through a static method that dereferences a pointer argument

Objective C(++) Insanity -- simple assignement to a single float variable results in {{{CRAZY}}} values in another variable

memberA is defined in the header of ClassA.
memberB is defined in the header of ClassB.
ClassB is a subclass of ClassA
Inside an instance of ClassB, setting memberA via simple assignment:
memberA = 0.05
...also changes memberB, but to a crazy number -- 1028443341. Additionally, assigning 0.05 to memberA results in memberA showing up in the debugger as 5.33083531e-38.
Both variables are floats, neither is a pointer. I'm almost certianly making some noob mistake, but I don't have any clue what it might be. What sort of screw-up might make it so assigning a value to one variable results in crazy values appearing in two variables?
********************* Edit **********************
I narrowed the problem down to some "trickiness" I'd done in order to get C++ member variables:
Thanks for all the thoughts folks. It's dangerous letting a noob like me at this low-level language stuff! Here's where the problem was:
#interface LoopyPulser : NSObject{
float _pulseRate;
UInt32 tickInterval;
UInt32 step;
InMemoryAudioFile * audioFilePlayer;
#ifdef __cplusplus
ADSR* env;
StkFrames* audioFrames;
# endif
Pattern * pattern;
float loopLengthRatio;
float volume;
}
I read about this #ifdef __cplusplus business somewhere else on SO, as a way to have C++ imports in header files which are then imported by Obj-C files. Seems to me now that this is a terrible idea, and most likely the cause of my crazy bug. If I remove the member vars inside the #ifdef __cplusplus, the insanity goes away.
So what's the best way to have C++ member variables in Obj-C++? Can I use ids maybe?
Sounds like memberA and memberB are floating point members of a class that is experiencing random memory corruption due to your program being written with some errors.
(1) Reference counting error (if you're not using GC) could result in the retain count hitting zero and an object being disposed of, that you are still holding your own reference to. Then the memory can be re-used and cause this interesting result.
(2) Some other pointer math, faulty indirection, or other C programming or ObjectiveC type mistakes (shoot self in foot).
Don't assume these are the only two things that are broken. How about putting the
following into your code:
// in your class declaration 1
int Magic1;
float MemberB;
int Magic2;
// same thing in class declaration 2:
int Magic1;
float MemberA;
int Magic2;
// somewhere else like your setup code for each of the two classes:
Magic1 = MAGIC_1;
Magic2 = MAGIC_2;
// somewhere else where the bug occurs
if (Magic1 != MAGIC_1) || (Magic2 != MAGIC_2) { ... do something helpful like NSLog(...) ... }