c++ Error when Testing library - c++

I am creating an Arduino library which takes two constructors for a personal project of mine, but for some reason I keep getting an error which is specific to types, first let me show you how the structure goes. so here is my files:
this is the header file:
#ifndef iGA_H
#define iGA_H
class iGA {
public:
getParameters(int soundA[], int soundB[], int parentId[]);
private:
int _soundA[];
int _soundB[];
int _parentId[];
}
the cpp file:
#include <iGA.h>
iGA::getParameters(int soundA[], int soundB[], int parentId[])
{
_soundA = soundA;
_soundB = soundB;
_parentId = parentId;
}
And this is how im pretty much calling the constructor in the sketch, within the setup() function:
#include <iGA>
iGA iga;
void setup() {
iga.getParameters(r, r1 , r2);
}
and here is the error:
In file included from /home/bargros/Dropbox/iGA__NewBild/iGA__NewBild.ino:34:0:/home/bargros/Arduino/libraries/iGA/iGA.h:10:58: error: ISO C++ forbids declaration of 'getParameters' with no type [-fpermissive]getParameters(int soundA[], int soundB[], int parentId[]);
I know the error has something to do with argument types or maybe im calling the constructor wrongly but I also tried calling it like this:
iGA iga = getParameters(etc,etc,etc);
im relatively new to c++ and im a little clueless as to what this error is telling me. Does anyone have any sort of idea of why this happens?

I believe two issues:
Issue 1: Your function should return something right? you may want to set it as void if it just meant to assign the parameters to the private members (it is a setter and not a get in your case). Add void in the proper locations both inside the class and when you write its definition.
Issue 2: I think that you can't send an array[] as a parameter. And I assume that you already know the size. You need, instead, to send a pointer that points to the first element of the array along with the size of the whole array. Then, once you receive the parameters, for every private member, you create a new array with the size received (or just fill the private member directly) and fill the values by iterating the received array using the pointer received.
Edit: I just checked and passing int array[] should be fine. So fixing issue one will fix your problem. See here for further documentation.

In C++ you have to be explicit that a function doesn't return anything, which you do by saying it returns void:
getParameters(int soundA[], int soundB[], int parentId[]);
needs to be
void getParameters(int soundA[], int soundB[], int parentId[]);
and
iGA::getParameters(int soundA[], int soundB[], int parentId[])
needs to be
void iGA::getParameters(int soundA[], int soundB[], int parentId[])

Related

Char array initialisation in class

I am trying to unit test a C++ application that I am building and I'm having an issue initializing the array when used in a class. I've tried alot of different methods of loading this information, the only ones that work are inefficient / not suitable.
Here is the hex array that I have (randomised the parts)
0x24,0x54,0x3b,0x72,0x8b,0x03,0x24,0x29,0x23,0x43,0x66,0x22,0x53,0x41,0x11,0x62,0x10
And header file for my unit test:
class MessageParsingTest : public CPPUNIT_NS::TestFixture {
CPPUNIT_TEST_SUITE(MessageParsingTest);
CPPUNIT_TEST(testIdentifyFirstMessageType);
CPPUNIT_TEST_SUITE_END();
public:
MessageParsingTest();
virtual ~MessageParsingTest();
void setUp();
void tearDown();
private:
void testIdentifyFirstMessageType();
void testIdentifySecondMessageType();
// data members for the hex array
unsigned char firstMessage[1500];
};
Then in my test case setUp function;
void MessageParsingTest::setUp() {
firstMessage = {0x24,0x54,0x3b,0x72,0x8b,0x03,0x24,0x29,0x23,0x43,0x66,0x22,0x53,0x41,0x11,0x62,0x10};
}
That it my latest failed attempt, it says its not valid during compilcation, as I expected, but at this point I was trying anything.
I've also tried things like (all in setUp function)
firstMessage << "\0x24\0x54\0x3b\0x72\0x8b\0x03\0x24\0x29\0x23\0x43\0x66\0x22\0x53\0x41\0x11\0x62\0x10";
firstMessage[1500] = "\0x24\0x54\0x3b\0x72\0x8b\0x03\0x24\0x29\0x23\0x43\0x66\0x22\0x53\0x41\0x11\0x62\0x10";
and a few other crazy ways, Does anyone know the proper way to load this data? the only way I've had it working so far is with either no data member declaration and straight up defining it and initializing in one line (but then I cant access in the test cases) or doing it one by one like firstMessage[0] = 0x24; etc.
I understand that there will be a simple, proper way of doing this and considering what the application actually does, this part should be the easiest.
You have few options:
Initialize arrays in constructor MesssageParsingTest using syntax : firstMessage{0x24,0x54,0x3b,0x72,0x8b,0x03,0x24,0x29,0x23,0x43,0x66,0x22,0x53,0x41,0x11,0x62,0x10}
in initializer list.
Create static const array containing your message, and either copy it to member variable using memcpy, or use static member and get rid of firstMessage member variable.
Declare const static member in .h inside class definition:
static const unsigned char kFirstMessage[];
and define + initialize it in .ccp
const unsigned char MessageParsingTest::kFirstMessage[] = "\0x24\0x54\0x3b\0x72\0x8b\0x03\0x24\0x29\0x23\0x43\0x66\0x22\0x53\0x41\0x11\0x62\0x10";
I would prefer static const member if you do not intend to modify this array later, since it makes the intention cleaner.
Here is one way to do it.
void MessageParsingTest::setUp()
{
unsigned char x[] = {0x24,0x54,0x3b,0x72,0x8b,0x03,0x24,0x29,0x23,0x43,0x66,0x22,0x53,0x41,0x11,0x62,0x10};
::memcpy(firstMessage, x, sizeof(x));
}
If you are using C++11, you can also initialize the firstMessage in the class member initialization list as
MessageParsingTest::MessageParsingTest() :
firstMessage{0x24,0x54,0x3b,0x72,0x8b,0x03,0x24,0x29,0x23,0x43,0x66,0x22,0x53,0x41,0x11,0x62,0x10},
...
You can use a temporary buffer and then copy into you member as this:
void MessageParsingTest::setUp() {
unsigned char tmp[1500] = {0x24,0x54,0x3b,0x72,0x8b,0x03,0x24,0x29,0x23,0x43,0x66,0x22,0x53,0x41,0x11,0x62,0x10};
memcpy(firstMessage, tmp, 1500);
}

C++ header functions

Sorry for asking a beginners question. I'm quiet familiar with Java, C# ...
but I have to write an OpenGL Program in C++ and there is something I don't understand:
I have to parse a text file to get vertices and put them into a vector. So I wrote a method that receives my vector of Vertex objects.
It works when I define the method before I call it
std::vector<AESParser::Vertex> vertices;
void parseVertices(std::vector<AESParser::Vertex> &verts){
...
}
...
parseVertices(vertices);
But fails when doing it the other way around. So I understand I have to declare it in the header file. So I wrote something like this:
*** Header ***
class AESParser
{
public:
struct Vertex{
float x;
float y;
float z;
};
AESParser();
virtual ~AESParser();
void read();
protected:
private:
int readNumVertices(std::fstream &stream);
int readNumFaces(std::fstream &stream);
void parseVertices(std::vector<Vertex> &verts);
Vertex readVertex(std::fstream &stream);
};
I know there are probably many more mistakes since I never did C++ but the main problem with this is, that I get the following error message:
undefined reference to `AESParser::parseVertices(std::vector<AESParser::Vertex, std::allocator<AESParser::Vertex> >&)'
So something seems to be wrong with the "parseVertices()" method and I don't see what. It works for the others like "readNumVertices()".
Thanks for your help!
Your function belongs to the AESParser class, so you need to define it as such
void AESParser::parseVertices(std::vector<AESParser::Vertex> &verts){
...
}
When you have the function definition written as
void parseVertices(std::vector<AESParser::Vertex> &verts)
Then it is a free function (doesn't belong to a class) that happens to have the same name, return the same type, and take the same arguments. But it is a different function.
Note in the first version, there is a AESParser:: scope appended to the front of the function name.

C++ global extern constant defined at runtime available across multiple source files

I have an integer constant that is to be defined at runtime. This constant needs to be available globally and across multiple source files. I currently have the following simplified situation:
ClassA.h declares extern const int someConstant;
ClassA.cpp uses someConstant at some point.
Constants.h declares extern const int someConstant;
main.cpp includes ClassA.h and Constants.h, declares const int someConstant, and at some point during main() tries to initialize someConstant to the real value during runtime.
This works flawlessly with a char * constant that I use to have the name of the program globally available across all files, and it's declared and defined exactly like the one I'm trying to declare and define here but I can't get it to work with an int.
I get first an error: uninitialized const ‘someConstant’ [-fpermissive] at the line I'm declaring it in main.cpp, and later on I get an error: assignment of read-only variable ‘someConstant’ which I presume is because someConstant is getting default initialized to begin with.
Is there a way to do what I'm trying to achieve here? Thanks in advance!
EDIT (per request from #WhozCraig): Believe me: it is constant. The reason I'm not posting MCVE is because of three reasons: this is an assignment, the source is in Spanish, and because I really wanted to keep the question as general (and reusable) as possible. I started out writing the example and midway it striked me as not the clearest question. I'll try to explain again.
I'm asked to build a program that creates a process that in turn spawns two children (those in turn will spawn two more each, and so on). The program takes as single argument the number of generations it will have to spawn. Essentially creating sort of a binary tree of processes. Each process has to provide information about himself, his parent, the relationship with the original process, and his children (if any).
So, in the example above, ClassA is really a class containing information about the process (PID, PPID, children's PIDs, degree of relation with the original process, etc). For each fork I create a new instance of this class, so I can "save" this information and print it on screen.
When I'm defining the relationship with the original process, there's a single point in which I need to know the argument used when calling the program to check if this process has no children (to change the output of that particular process). That's the constant I need from main: the number of generations to be spawned, the "deepness" of the tree.
EDIT 2: I'll have to apologize, it's been a long day and I wasn't thinking straight. I switched the sources from C to C++ just to use some OO features and completely forgot to think inside of the OO paradigm. I just realized while I was explaining this that I might solve this with a static/class variable inside my class (initialized with the original process), it might not be constant (although semantically it is) but it should work, right? Moreover I also realized I could just initialize the children of the last generation with some impossible PID value and use that to check if it is the last generation.
Sorry guys and thank you for your help: it seems the question was valid but it was the wrong question to ask all along. New mantra: walk off the computer and relax.
But just to recap and to stay on point, it is absolutely impossible to create a global constant that would be defined at runtime in C++, like #Jerry101 says?
In C/C++, a const is defined at compile time. It cannot be set at runtime.
The reason you can set a const char *xyz; at runtime is this declares a non-const pointer to a const char. Tricky language.
So if you want an int that can be determined in main() and not changed afterwards, you can write a getter int xyz() that returns a static value that gets initialized in main() or in the getter.
(BTW, it's not a good idea to declare the same extern variable in more than one header file.)
As others have mentioned, your variable is far from being constant if you set it only at run-time. You cannot "travel back in time" and include a value gained during the program's execution into the program itself before it is being built.
What you can still do, of course, is to define which components of your program have which kind of access (read or write) to your variable.
If I were you, I would turn the global variable into a static member variable of a class with a public getter function and private setter function. Declare the code which needs to set the value as a friend.
class SomeConstant
{
public:
static int get()
{
return someConstant;
}
private:
friend int main(); // this should probably not be `main` in real code
static void set(int value)
{
someConstant = value;
}
static int someConstant = 0;
};
In main:
int main()
{
SomeConstant::set(123);
}
Anywhere else:
void f()
{
int i = SomeConstant::get();
}
You can further hide the class with some syntactic sugar:
int someConstant()
{
return SomeConstant::get();
}
// ...
void f()
{
int i = someConstant();
}
Finally, add some error checking to make sure you notice if you try to access the value before it is set:
class SomeConstant
{
public:
static int get()
{
assert(valueSet);
return someConstant;
}
private:
friend int main(); // this should probably not be `main` in real code
static void set(int value)
{
someConstant = value;
valueSet = true;
}
static bool valueSet = false;
static int someConstant = 0;
};
As far as your edit is concerned:
Nothing of this has anything to do with "OO". Object-oriented programming is about virtual functions, and I don't see how your problem is related to virtual functions.
char * - means ur creating a pointer to char datatype.
int - on other hand creates a variable. u cant declare a const variable without value so i suggest u create a int * and use it in place of int. and if u are passing it into functions make it as const
eg: int *myconstant=&xyz;
....
my_function(myconstant);
}
//function decleration
void my_function(const int* myconst)
{
....
}
const qualifier means variable must initialized in declaration point. If you are trying to change her value at runtime, you get UB.
Well, the use of const in C++ is for the compiler to know the value of a variable at compile time, so that it can perform value substitution(much like #define but much more better) whenever it encounters the variable. So you must always assign a value to a const when u define it, except when you are making an explicit declaration using extern. You can use a local int to receive the real value at run time and then you can define and initialize a const int with that local int value.
int l_int;
cout<<"Enter an int";
cin>>l_int;
const int constNum = l_int;

deque.push_front() giving error "expression must have class type"

I am trying to initialize a deque with pointers to a user defined struct, Tile, in order to eliminate unnecessary copying.
My code looks like this:
Tile *start = new Tile(0,0,0, 'q', nullptr);
deque<Tile*> search();
search.push_front(start);
The above code is located in main.cpp.
The Tile struct looks like this, and is contained in hunt.h:
struct Tile
{
int row; int col; int farm;
char tile;
Tile * added_me;
Tile(int f, int r, int c, char t, Tile * a) :
farm(f), row(r), col(c), tile(t), added_me(a){}
};
The layout of my program is as follows:
main.cpp: includes "io.h"
io.h: includes "hunt.h", various standard libraries
hunt.h: includes vector, deque, Tile struct
However, I am getting an error in main.cpp when I try to push_front(start): expression must have class type." I wasn't sure if a possible fault in my #includes was causing this error, so please let me know if this is the case. Otherwise, I am not entirely sure how to fix this error.
Thanks in advance!
When you write
deque<Tile*> search();
you aren't actually declaring a deque<Tile*> named search and using the default constructor. Instead, C++ interprets this as a function declaration for a function named search that takes no parameters and returns a deque<Tile*>. You can't call push_front on a function, hence the error.
To fix this, either remove the () from the declaration of the variable, or replace them with {} (if you're using a C++11-compliant compiler). That will cause C++ to (correctly) interpret that you want to declare a variable.
Hope this helps!

Passing class pointer in to constructor for class

Working on a collaborative project (was hoping two would be easier than one - how wrong was I...?)
Basically, what we're trying to do is a bit like this:
class first
{
first(int * num);
};
class second
{
second(first * frst);
first * frt;
};
first::first(int * num)
{
}
second::second(first * frst)
{
frt = frst;
}
There is a bit of an issue though, we can't include our Core.h file, since that contains includes to the files we're already including (there is sense somewhere there). Short version is, we're having to do something a bit more like this:
#ifndef PLAYERSTRUCTURE
#define PLAYERSTRUCTURE
// DO NOT INCLUDE CORE IN THIS FILE
class Core;
struct PlayerMem
{
int cid;
int y, x, z;
};
class Player
{
public:
Player::Player(Core * coar);
Player::Player(void);
Player::~Player(void);
};
#endif
The Core class is declared but not defined, will this cause issues if we try to access it from within the Player class, using Core->GetSomething() etc?
Thanks
You're forwarding declaration. It's OK.
When you can use Core->GetSomething() without any compilation error then it means class Core is defined and it's not an incomplete type. So, there is no issue to use it. Just make sure you're passing a valid pointer to Core when constructing Player.
Note: In your code you're passing a pointer to a class type not a reference.