C++ class instance identifier undeclared - c++

So, I'm trying to compile my code, but the compiler keeps complaining that "'mysnake' undeclared (first use this function)", but I declared it.
This is my Main.cpp, wehre it is declared.
#include "Class.h"
#include "Snake.h"
int main(int argc, char* args[]){
Prog run;
if((run.Init())==false){
return(1);
}
Snake mysnake;
if(run.LoadFiles()==false){
return(1);
}
run.MainLoop();
if(run.Draw()==false){
return(1);
}
run.CleanUp();
return(0);
}
And this is the file that makes the compiler complain (AFAIK it's the first file with any reference to 'mysnake' that gets compiled)
#include "Class.h"
#include<sstream>
#include "Snake.h"
bool Prog::Draw(){
std::stringstream message;
SDL_Rect position;
SDL_BlitSurface(image, NULL, screen, NULL);
int s=mysnake.EndSnake();
message<<"Your snake was "<<s<<" blocks long.";
msg=TTF_RenderText_Solid(font, message.str().c_str(), font_color);
if(msg==NULL){
return(false);
}
position.x=(WWIDTH-msg->w)/2;
position.y=(WHEIGHT-msg->h)/2;
SDL_BlitSurface(msg, NULL, screen, &position);
SDL_Flip(screen);
return(true);
}
I have thought about it for over an hour and I still can't understand why it does this. By the way I'm using Bloodshed Dev C++
I'd be very grateful for help.

Inside your Draw function there is no variable declared called mysnake. That function can't see the mysnake that's declared in main because it is local to main. You need to pass your mysnake object to the Draw function so that it knows which snake you're actually talking about.
To do that, give Draw an argument of type const Snake&, a "reference to const Snake" (or take away the const if EndSnake is a non-const member function):
bool Prog::Draw(const Snake& snake) {
// ...
}
And when you call Draw in main, do this:
run.draw(mysnake);
Now your Draw function has a variable called snake which was passed in from main. Because the argument is a reference, the Snake object that it sees is exactly the same object as in main. If the argument had been of type Snake instead of const Snake&, then you would get a copy of the mysnake from main.
Some extra advice:
We usually write conditions like (run.Init())==false as just !run.init() - it reads much better. Returning is also usually written as return true;, rather than return(true);, but that's up to you.

The fact that mysnake is declared in main does not allow one to use it in Prog. You probably want to transmit a reference to mysnake to the Draw method.
Through the constructor or through the call to the method.
Prog run(mysnake);
run.draw();
or
run.draw(mysnake);

Related

Errors when using pointers to static functions in C / C ++

I am compiling with g ++ an application that calls some functions defined in a "C" library.
Some of the functions that I need to call are defined as static in the original ".c" file (I know that when a function is defined static it is so that it is not called from outside of that file, but despite that, I need to call them from outside of the same).
I am going to execute them from outside that file using pointers to functions and to see how they work, I have prepared this example, where I want to execute in file_2.c the static functions fun5 and fun6 defined in file_1.c
file_1.h
--------
#ifndef FILE_1_H
#define FILE_1_H
int (*getPtrFun6(void*))(int,char,char*);
#endif
file_1.c
--------
#include <stdio.h>
int(*ptr_fun5)(int,int);
static int fun5(int p1, int p2)
{
printf("fun5 called.\n");
ptr_fun5 = &fun5;
return p1 + p2;
}
static int fun6(int p1, char p2, char* p3)
{
printf("fun6 called with p1 = %d, p2 = %c, p3 = %s.\n", p1, p2, p3);
return p1;
}
int (*getPtrFun6(void*))(int,char,char*)
{
return fun6;
}
file_2.c
--------
#include <stdio.h>
#include <cstring>
#include "file_1.h"
extern int(*ptr_fun5)(int,int);
extern int(*ptr_fun6)(int,char,char*);
int main(void)
{
int returnValue = 0;
// To run fun5
returnValue = (ptr_fun5)(15, 32);
printf ("Returns %d\n", returnValue);
// To run fun6
char myString[50];
memset(myString,0,50);
strncpy(myString,"THIS IS OK",10);
ptr_fun6 = getPtrFun6();
returnValue = (ptr_fun6)(32, 'v', myString);
printf ("Returns %d\n", returnValue);
return 0;
}
I compile the program with the command:
g++ file_2.c file_1.c -o static_example
As you can see from the source code, I have tried two different ways to use a pointer to a static function.
If I comment on everything about fun6 in the source code, compile it and run it (just call fun5) I get the error "Segmentation fault".
On the other hand, if I comment on everything related to fun5 in the source code and leave only fun6, when compiling the program, I get these errors:
file_2.c: In function ‘int main()’:
file_2.c:20:25: error: too few arguments to function ‘int (* getPtrFun6(void*))(int, char, char*)’
ptr_fun6 = getPtrFun6();
^
In file included from file_2.c:4:
file_1.h:4:7: note: declared here
int (*getPtrFun6(void*))(int,char,char*);
^~~~~~~~~~
I have looked at various forums and tutorials on the web and I don't see what the error is, so I would need some help on the correct way to use the pointers to fun5 and fun6.
(just call fun5) I get the error "Segmentation fault".
Because fun5 is uninitialized, it doesn't point anywhere.
when compiling the program, I get these errors: ... error: too few arguments to function
So why did you declare it to take a void* as parameter? If you don't want that, then it should be void.
General advise:
Get rid of global variables with extern.
Use typedef whenever dealing with function pointers, so that the code can be read by humans. Evidentally, int (*getPtrFun6(void*))(int,char,char*) isn't readable even by yourself.
int (*getPtrFun6(void*))(int,char,char*);
Confusing syntax is leading to wrong prototype and declaration.
The easy to read way (function pointers are same as "normal" pointers):
typedef int fun6type(int, char, char *);
fun6type *getPtrFun6(void);
fun6type *getPtrFun6(void)
{
return fun6;
}
Hard to read way:
int (*getPtrFun6_1(void))(int, char, char *);
int (*getPtrFun6_1(void))(int, char, char *)
{
return fun6;
}
int foo(void)
{
int (*f)(int, char, char *) = getPtrFun6_1();
return f(1, 'a', "Test");
}
Test it yourself
https://godbolt.org/z/erh63jTc8
If I comment on everything about fun6 in the source code, compile it
and run it (just call fun5) I get the error "Segmentation fault".
Function pointer has to reference a valid function before it is dereferenced (called) as any other pointer. Your one is not initialized and it is not referencing a valid function.
BTW It is rather C code (not C++). In C++ use of function pointers (and generally pointers) should be avoided.
returnValue = (ptr_fun5)(15, 32); does not work because ptr_fun5 is initialized to a null pointer and is not given any other value until the statement ptr_fun5 = &fun5; inside fun5 is executed, which does not happen until fun5 is called.
One way to fix that is to delete int(*ptr_fun5)(int,int); and put int (*ptr_fun5)(int, int) = fun5; after the declaration of fun5. Then it will be initialized to the address of fun5.

Call a non-static method from no object using std::function

While doing some random-ish, weird-ish things to understand a little bit more C++ (just to say I'm still a newbie), I came across something I can't properly understand : I'm currently using SFML which provides a few methods to create and manage a window, namely this method to close it: void sf::RenderWindow::close(). It doesn't take any argument, and it can't be called directly but through an instantiated object.
sf::RenderWindow::close(); // error
My problem is the following code :
sf::RenderWindow window(sf::VideoMode(800, 600), "test"); // added after edit
const std::function <void(sf::RenderWindow &)> callback(sf::RenderWindow::close);
// callback();
callback(window); // closes the window
I'm not sure to understand what's happening here as I'm not using any object... even anonymous at first sight... I guess...
If someone can enlighten me, I'd really appreciate it.
Thanks you.
Edit:
My mistake, yes there's an object.
#include <iostream>
#include <functional>
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "test");
const std::function <void(sf::RenderWindow &)> call(sf::RenderWindow::close);
call(window);
return 0;
}
Actually, I understand this as if it were sf::RenderWindow::close(window), similarly to metatables in lua I suppose.
It's linked to the concept of Callable:
Since the stored target of the std::function (i.e. sf::RenderWindow::close) is a pointer to member function and the first argument (i.e. window) is a (reference to) an object of type RenderWindow, then the invocation of the function object is equivalent to window.close().
You could also have written something along those lines:
std::function<void(sf::RenderWindow*)> call = &sf::RenderWindow::close;
call(&window);
Below a code sample that doesn't involve SFML:
#include <iostream>
#include <functional>
class Window {
public:
void close() {std::cout << "close" << std::endl; }
};
int main(int argc, const char * argv[]) {
Window w;
std::function<void(Window&)> f = &Window::close;
f(w);
std::function<void(Window*)> g = &Window::close;
g(&w);
return 0;
}

Global variable is out of scope! What the heck?

Houston, we have a problem. Here's a simplified code version:
main.cpp
#include <SFML/Graphics.hpp>
#include "global.hpp"
#include "init.hpp"
int main(void)
{
createWindow();
loadLevel();
while(window.isOpen())
{
if(!handleEvents()) window.close();
window.clear();
window.draw(bgSprite);
window.display();
}
return 0;
}
global.hpp
sf::Texture bgTexture;
sf::Sprite bgSprite;
init.hpp
void loadGraphics(void)
{
bgTexture.loadFromFile("bg.png");
bgSprite.setTexture(bgTexture);
}
Even though the texture and sprite variables are global, window screen remains black.
However, when I put the variables inside the main() function, everything works perfectly. Could someone explain why is this happening?
I thought that you can call global variables whenever and wherever you wish, and they will disappear only when the program itself terminates.
By the way, I also tried putting the variables and loadGraphics() right behind main() (not in a header file), still, no results. I also commented out all additional code, so the problem definitely lies here.
EDIT: I AM AN IDIOT!
I didn't call the loadGraphics(function). Thank You! I'm sorry for your wasted time. Everything started working correctly. Sad lol - spent over 1 hour fixing this thing...
You never call loadGraphics. Call that at the start of main, and your program will probably work.
But you'd almost certainly be better off without globals; and in any case, you don't want to define them in a header since that will break the One Definition Rule if you include that header more than once in your program.
If you really do want them to be global, then declare them (without definining them) in the header:
extern sf::Texture bgTexture;
and define them (as you've done) in just one source file.
Likewise, you shouldn't define a non-inline function in a header for the same reason. Either leave it in the header and make it inline:
inline void loadGraphics() // void parameter is pointless
{
bgTexture.loadFromFile("bg.png");
bgSprite.setTexture(bgTexture);
}
or just declare it in the header
void loadGraphics();
and move your definition into a source file.
You might avoid globals by encapsulating them in a class:
struct Graphics {
Graphics(std::string file) {
texture.loadFromFile(file);
sprite.setTexture(texture);
}
sf::Texture texture;
sf::Sprite sprite;
};
and instantiating this in main
Graphics graphics("bg.png");
//...
window.draw(graphics.sprite);
When you place a variable global to a project, you need to place it in a .cpp file and make a .h which declares it as extern. This allows for all the files to refer to the same global variable.
In your case, you'd change the code as so:
global.hpp
extern sf::Texture bgTexture;
extern sf::Sprite bgSprite;
global.cpp
sf::Texture bgTexture;
sf::Sprite bgSprite;
Also, as in Mike's answer, you never call loadGraphics().
Personally, I'd put that in another .cpp file and put a .hpp file with the prototype.
Also, when compiling, you'll have to compile all the cpp files together into a single executable (i.e. link them together)
bgTexture and bgSprite are never set. I don't see any call to your loadGraphics function in the main.
You should start by calling your loadGraphics function

No matching function call to 'pthread_create'

I'm using Xcode and C++ to make a simple game.
The problem is the following code:
#include <pthread.h>
void *draw(void *pt) {
// ...
}
void *input(void *pt) {
// ....
}
void Game::create_threads(void) {
pthread_t draw_t, input_t;
pthread_create(&draw_t, NULL, &Game::draw, NULL); // Error
pthread_create(&input_t, NULL, &Game::draw, NULL); // Error
// ...
}
But Xcode gives me the error: "No matching function call to 'pthread_create'". I haven't an idea 'cause of I've included pthread.h already.
What's wrong?
Thanks!
As Ken states, the function passed as the thread callback must be a (void*)(*)(void*) type function.
You can still include this function as a class function, but it must be declared static. You'll need a different one for each thread type (e.g. draw), potentially.
For example:
class Game {
protected:
void draw(void);
static void* game_draw_thread_callback(void*);
};
// and in your .cpp file...
void Game::create_threads(void) {
// pass the Game instance as the thread callback's user data
pthread_create(&draw_t, NULL, Game::game_draw_thread_callback, this);
}
static void* Game::game_draw_thread_callback(void *game_ptr) {
// I'm a C programmer, sorry for the C cast.
Game * game = (Game*)game_ptr;
// run the method that does the actual drawing,
// but now, you're in a thread!
game->draw();
}
compilation of threads using pthread is done by providing options -pthread.
Such as compiling abc.cpp would require you to compile like g++ -pthread abc.cpp else would
give you an error like undefined reference topthread_create collect2: ld returned 1 exit status` . There must be some similar way to provide pthread option.
You're passing a member function pointer (i.e. &Game::draw) where a pure function pointer is required. You need to make the function a class static function.
Edited to add: if you need to invoke member functions (which is likely) you need to make a class static function which interprets its parameter as a Game* and then invoke member functions on that. Then, pass this as the last parameter of pthread_create().

How can I perform pre-main initialization in C/C++ with avr-gcc?

In order to ensure that some initialization code runs before main (using Arduino/avr-gcc) I have code such as the following:
class Init {
public:
Init() { initialize(); }
};
Init init;
Ideally I'd like to be able to simply write:
initialize();
but this doesn't compile...
Is there a less verbose way to achieve the same effect?
Note: the code is part of an Arduino sketch so the main function is automatically generated and cannot be modified (for example to call initialize before any other code).
Update: ideally the initialization would be performed in the setup function, but in this case there is other code depending on it which occurs before main.
You can use GCC's constructor attribute to ensure that it gets called before main():
void Init(void) __attribute__((constructor));
void Init(void) { /* code */ } // This will always run before main()
You can make the above very slightly shorter by giving "initialize" a return type, and using that to initialize a global variable:
int initialize();
int dummy = initialize();
However, you need to be careful with this, the standard does not guarantee that the above initialization (or the one for your init object) takes place before main is run (3.6.2/3):
It is implementation-defined whether or not the dynamic initialization (8.5, 9.4, 12.1, 12.6.1) of an object of namespace scope is done before the first statement of main.
The only thing that is guaranteed is that the initialization will take place before 'dummy' is ever used.
A more intrusive option (if it's possible) might be to use "-D main=avr_main" in your makefile. You could then add your own main as follows:
// Add a declaration for the main declared by the avr compiler.
int avr_main (int argc, const char * argv[]); // Needs to match exactly
#undef main
int main (int argc, const char * argv[])
{
initialize ();
return avr_main (argc, argv);
}
At least here you're guaranteed that the initialization will take place when you expect.
Here's a somewhat evil method of achieving this:
#include <stdio.h>
static int bar = 0;
int __real_main(int argc, char **argv);
int __wrap_main(int argc, char **argv)
{
bar = 1;
return __real_main(argc, argv);
}
int main(int argc, char **argv)
{
printf("bar %d\n",bar);
return 0;
}
Add the following to the linker flags: --wrap main
eg.
gcc -Xlinker --wrap -Xlinker main a.c
The linker will replace all calls to main with calls to __wrap_main, see the ld man page on --wrap
Your solution in simple and clean. What you can additionally do is to put your code in anonymous namespace. I don't see any need to make it better than that :)
If you are using the Arduino environment, is there any reason you can't place it in the setup method?
Of course, this is after the Arduino-specific hardware setup, so if you have such low-level stuff that it really has to go before main, then you need some constructor magic.
UPDATE:
Ok, if it has to be done before the main I think the only way is to use a constructor like you already do.
You can always make a preprocessor macro of it:
#define RUN_EARLY(code) \
namespace { \
class Init { \
Init() { code; } \
}; \
Init init; \
}
Now this should work:
RUN_EARLY(initialize())
But it's not really making things shorter, just moving the verbose code around.
You can use the ".init*" sections to add C code to be run before main() (and even the C runtime). These sections are linked into the executable at the end and called up at specific time during program initialization. You can get the list here:
http://www.nongnu.org/avr-libc/user-manual/mem_sections.html
.init1 for example is weakly bound to __init(), so if you define __init(), it will be linked and called first thing. However, the stack hasn't been setup, so you have to be careful in what you do (only use register8_t variable, not call any functions).
Use static members of classes. They are initialized before entering to main. The disadvantage is that you can't control the order of the initialization of the static class members.
Here is your example transformed:
class Init {
private:
// Made the constructor private, so to avoid calling it in other situation
// than for the initialization of the static member.
Init() { initialize(); }
private:
static Init INIT;
};
Init Init::INIT;
Sure, you put this in one of your your header files, say preinit.h:
class Init { public: Init() { initialize(); } }; Init init;
and then, in one of your compilation units, put:
void initialize(void) {
// weave your magic here.
}
#include "preinit.h"
I know that's a kludge but I'm not aware of any portable way to do pre-main initialization without using a class constructor executed at file scope.
You should also be careful of including more than one of these initialization functions since I don't believe C++ dictates the order - it could be random.
I'm not sure of this "sketch" of which you speak but would it be possible to transform the main compilation unit with a script before having it passed to the compiler, something like:
awk '{print;if (substr($0,0,11) == "int main (") {print "initialize();"};}'
You can see how this would affect your program because:
echo '#include <stdio.h>
int main (void) {
int x = 1;
return 0;
}' | awk '{
print;
if (substr($0,0,11) == "int main (") {
print " initialize();"
}
}'
generates the following with the initialize() call added:
#include <stdio.h>
int main (void) {
initialize();
int x = 1;
return 0;
}
It may be that you can't post-process the generated file in which case you should ignore that final option, but that's what I'd be looking at first.
There is how I perform pre-main coding.
There are sever init sections executed before main, refers to http://www.nongnu.org/avr-libc/user-manual/mem_sections.html initN sections.
Anyhow, this only works on -O0 optimization for some reason. I still try to find out which option "optimized" my pre-main assembly code away.
static void
__attribute__ ((naked))
__attribute__ ((section (".init8"))) /* run this right before main */
__attribute__ ((unused)) /* Kill the unused function warning */
stack_init(void) {assembly stuff}
Update, it turns out I claimed this function is unused, leading to optimize the routine away. I was intended to kill function unused warning. It is fixed to used used attribute instead.