Function 'not declared in this scope', but it is! Isn't it? - c++

'initPhysics' was not declared in this scope.
I have simplified my program as much as I could; here it is:
helloworld.hpp
#ifndef HELLOWORLD_HPP
#define HELLOWORLD_HPP
class testWorld {
public:
testWorld() {}
~testWorld() {}
void initPhysics();
};
#endif
hello.cpp
#include "helloworld.hpp"
#include <iostream>
using namespace std;
void testWorld::initPhysics() {
cout << "Initiating physics..." << endl;
}
int main(int argc,char** argv) {
cout << "Hello World!" << endl;
testWorld* world;
world = new testWorld();
world<-initPhysics();
return 0;
}
I compile with the command
g++ -c hello.cpp
and get the error
hello.cpp: In function ‘int main(int, char**)’:
hello.cpp:14:21: error: ‘initPhysics’ was not declared in this scope
Why doesn't the compiler see the declaration of initPhysics, even though I included helloworld.hpp?

It should be world->initPhysics(), not world<-initPhysics()
Your version is being read as the expression "world is less than -1 multiplied by the result of the global function initPhysics()" and it's that global function that it can't find.
And although this is obviously test code, I'd just like to point out that if you allocate an object with new, you must explicitly delete it somewhere.

world<-initPhysics() should be world->initPhysics()?

Learn to read the -> operator (not <-!) in ptr->member as "member in whatever ptr points to", in other words: it is a somewhat literal representation of an actual pointer. So in your case it should be
world->initPhysics(); // note the ->, not <-
However, while this answers your question, it's far from sufficient. There's several other problems with your code.
There's no need to first create an uninitialized pointer, and then initialize it. That's error-prone, and you should instead initialize it immediately:
testWorld* world = new testWorld();
world->initPhysics();
Note that in C++ every object created using the new operator needs to be destroyed explicitly using the delete operator:
delete world; // sounds scary, BTW
You seem to be coming from a language like Java or C#, where everything must be new'd. In C++ this is not true. By default you should create objects on the stack, rather than on the heap:
testWorld world;
world.initPhysics();
But there's still a problem with your code. What you have now is what's known as two-phase construction. As a user of your class I need to remember to call an initialization function before I use an instance of it. But that's what constructors are for! A constructor should fully initialize an object, so that it is in a usable state. You should call your initialization function from the constructor instead:
testWorld() {initPhysics();}
Physics is an integral part of the world, and shouldn't be added as an afterthought. :)

You want world->initPhysics(); instead of world<-initPhysics();

world<-initPhysics();
Here, your arrow is in the wrong direction. You should have :
world->initPhysics();

world<-initPhysics(); should be world->initPhysics();

Related

Does int main() need a declaration on C++?

I was taught that functions need declarations to be called. To illustrate, the following example would give me an error as there is no declaration for the function sum:
#include <iostream>
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
// main.cpp:4:36: error: use of undeclared identifier 'sum'
// std::cout << "The result is " << sum(1, 2);
// ^
// 1 error generated.
To fix this, I'd add the declaration:
#include <iostream>
int sum(int x, int y); // declaration
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
Why the main function doesn't need the declaration, as other functions like sum need?
A definition of a function is also a declaration of a function.
The purpose of a declaring a function is to make it known to the compiler. Declaring a function without defining it allows a function to be used in places where it is inconvenient to define it. For example:
If a function is used in a source file (A) other than the one it is defined in (B), we need to declare it in A (usually via a header that A includes, such as B.h).
If two or more functions may call each other, then we cannot define all those functions before the others—one of them has to be first. So declarations can be provided first, with definitions coming afterward.
Many people prefer to put “higher level” routines earlier in a source file and subroutines later. Since those “higher level” routines call various subroutines, the subroutines must be declared earlier.
In C++, a user program never calls main, so it never needs a declaration before the definition. (Note that you could provide one if you wished. There is nothing special about a declaration of main in this regard.) In C, a program can call main. In that case, it does require that a declaration be visible before the call.
Note that main does need to be known to the code that calls it. This is special code in what is typically called the C++ runtime startup code. The linker includes that code for you automatically when you are linking a C++ program with the appropriate linker options. Whatever language that code is written in, it has whatever declaration of main it needs in order to call it properly.
I was taught that functions need declarations to be called.
Indeed. A function must be declared before it can be called.
why we don't add a declaration for the main function?
Well, you didn't call main function. In fact, you must not call main at all1, so there is never a need to declare main before anything.
Technically though, all definitions are also declarations, so your definition of main also declares main.
Footnote 1: The C++ standard says it's undefined behaviour to call main from within the program.
This allows C++ implementations to put special run-once startup code at the top of main, if they aren't able to have it run earlier from hooks in the startup code that normally calls main. Some real implementations do in fact do this, e.g. calling a fast-math function that sets some FPU flags like denormals-are-zero.
On a hypothetical implementation, calling main could result in fun things like re-running constructors for all static variables, re-initializing the data structures used by new/delete to keep track of allocations, or other total breakage of your program. Or it might not cause any problem at all. Undefined behaviour doesn't mean it has to fail on every implementation.
The prototype is required if you want to call the function, but it's not yet available, like sum in your case.
You must not call main yourself, so there is no need to have a prototype. It's even a bad a idea to write a prototype.
No, the compiler does not need a forward declaration for main().
main() is a special function in C++.
Some important things to remember about main() are:
The linker requires that one and only one main() function exist when creating an executable program.
The compiler expects a main() function in one of the following two forms:
int main () { /* body */ }
int main (int argc, char *argv[]) { /* body */ }
where body is zero or more statements
An additional acceptable form is implementation specific and provides a list of the environment variables at the time the function is called:
int main (int argc, char* argv[], char *envp[]) { /* body */ }
The coder must provide the 'definition' of main using one of these acceptable forms, but the coder does not need to provide a declaration. The coded definiton is accepted by the compiler as the declaration of main().
If no return statement is provided, the compiler will provide a return 0; as the last statement in the function body.
As an aside, there is sometimes confusion about whether a C++ program can make a call to main(). This is not recommended. The C++17 draft states that main() "shall not be used within a program." In other words, cannot be called from within a program. See e.g. Working Draft Standard for C++ Programming Language, dated "2017-03-21", Paragraph 6.6.1.3, page 66. I realize that some compilers support this (including mine), but the next version of the compiler could modify or remove that behavior as the standard uses the term "shall not".
It is illegal to call main from inside your program. That means the only thing that is going to call it is the runtime and the compiler/linker can handle setting that up.This means you do not need a prototype for main.
A definition of a function also implicitly declares it. If you need to reference a function before it is defined you need to declare it before you use it.
So writing the following is also valid:
int sum(int x, int y) {
return x + y;
}
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
If you use a declaration in one file to make a function known to the compiler before it is defined, then its definition has to be known at linking time:
main.cpp
int sum(int x, int y);
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
sum.cpp
int sum(int x, int y) {
return x + y;
}
Or sum could have its origin in a library, so you do not even compile it yourself.
The main function is not used/referenced in your code anywhere, so there is no need to add the declaration of main anywhere.
Before and after your main function the c++ library might execute some init and cleanup steps, and will call your main function. If that part of the library would be represented as c++ code then it would contain a declaration of int main() so that that it could be compiled. That code could look like this:
int main();
int __main() {
__startup_runtime();
main();
__cleanup_runtime();
}
But then you again have the same problem with __main so at some point there is no c++ anymore and a certain function (main) just represents the entry point of your code.
Nope. You can't call it anyway.
You only need forward declarations for functions called before they are defined. You need external declarations (which look exactly like forward declarations on purpose) for functions defined in other files.
But you can't call main in C++ so you don't need one. This is because the C++ compiler is allowed to modify main to do global initialization.
[I looked at crt0.c and it does have a declaration for main but that's neither here nor there].

C++ class filler syntax error

My class is as follows:
class stats {
public: int strength,
perception,endurance,charisma,inteligence,agility,luck,health,stamina,mana,karma;
};
As far as I know, there shouldn't be anything wrong with it, unless I need to set up a constructor and destructor.
I create my object using the following line:
stats* mainstat=new stats;
And I have the following function to "fill" objects of the said class:
void statfiller(stats* object, int table[]){
object->strength=table[0]; object->perception=table[1];
object->endurance=table[2]; object->charisma=table[3];
object->inteligence=table[4]; object->agility=table[5];
object->luck=table[6]; object->health=table[7];
object->stamina=table[8]; object->mana=table[9];
object->karma=table[10];
}
So, until then, no problem. At least, until the following:
I create a table with the data to fill, then feed it to my fill function.
int tablet[10]; tablet[0]=5; tablet[1]=5; tablet[2]=5; tablet[3]=5;
tablet[4]=5; tablet[5]=5; tablet[6]=5; tablet[7]=50; tablet[8]=50;
tablet[9]=50; tablet[10]=0;
statfiller(mainstat*,tablet);
When I do this, a compiling error comes up, stating the syntax of my function is incorrect.
Why is it so? Do I need to use pointer(*) or address(&)? Is there something I'm missing?
Odds are, the solution is very simple, but at the moment of typing this, I just don't see what's wrong with it ^^;
Solution to this problem was the following:
The function's syntax is "void statfiller(stats* object, int table[]) ", where the stats* object serves as reference, pointer to an object of stats class.
In the function's call "statfiller(mainstat*,tablet);", the mistake I made was calling a pointer of a stat object (in this case mainstat) instead of just putting in the object.

Using an object by calling class constructor explicitly vs by default initialization + assignment operator

Considering the following example:
#include <wx/bitmap.h>
int main()
{
wxBMPHandler h;
wxImage::AddHandler(&h);
wxBitmap bm = wxBitmap(200, 200);
bm.SaveFile("file.bmp", wxBITMAP_TYPE_BMP);
return 0;
}
Since I'm only using h to call AddHandler() and not for anything else, I'd like to avoid defining it altogether and do the whole thing in one line. So I thought about replacing that with:
wxImage::AddHandler(&wxBMPHandler());
which compiles fine, but calling SaveFile() won't work then; WxWidgets will present an error stating "No image handler for type 1 defined" at runtime.
I guess the object created inside the function call is temporary, but I'm not sure about that. If not, what am I missing, and how can I avoid defining h?
It's worth noting that AddHandler() has the following signature:
static void AddHandler( wxImageHandler *handler );
[Update]
In response to M.M's comment saying:
wxImage::AddHandler(&wxBMPHandler()); should fail to compile, unless
that class has overloaded operator& for rvalues
Since I couldn't find a definition for operator& in WxWidgets' source code, I created this test project:
#include <iostream>
#include <string>
using namespace std;
string* address = nullptr;
void testing(string* input)
{
*input = "Something else entirely";
address = input;
}
int main()
{
testing(&string("Life is a test"));
cout << *address << endl;
cin.get();
return 0;
}
It compiles fine, and runs without any "hard error" - the only caveat is that nothing is shown in the screen - (*address).empty() returns true.
I even defined my own class to test with, instead of std::string and yielded the same behavior (no compiler error, no runtime error, but no output).
I also tried this one-liner, as suggested by aichao, without success:
wxImage::AddHandler(shared_ptr<wxBMPHandler>(new wxBMPHandler()).get());
I've never used wxWidgets before, but according to the wxWidgets version 3.1.1 API docs here, you should call wxImage::AddHandler using a heap-allocated handler object:
wxImage::AddHandler(new wxBMPHandler);
Therefore, there is no need for defining h. Also according to the docs, the memory for this handler object is managed by the wxWidgets framework. Specifically, the docs says that the handler is a
heap-allocated handler object which will be deleted by wxImage if it is removed later by RemoveHandler() or at program shutdown.
There is also the static member function wxImage::CleanUpHandlers() to delete all registered image handlers. According to the docs:
This function is called by wxWidgets on exit.
Therefore, you do not have to delete the handler yourself unless you specifically want to (i.e., to free up some memory).
Hope this helps.
In wxImage::AddHandler(&wxBMPHandler());, the lifetime of the temporary stop at the end of the expression, so you have dangling pointer.
In
wxBMPHandler h;
wxImage::AddHandler(&h);
wxBitmap bm = wxBitmap(200, 200);
bm.SaveFile("file.bmp", wxBITMAP_TYPE_BMP);
h outlives the call bm.SaveFile("file.bmp", wxBITMAP_TYPE_BMP);.
You will have similar issue with
{
wxBMPHandler h;
wxImage::AddHandler(&h);
} // End of life time of h
wxBitmap bm = wxBitmap(200, 200);
bm.SaveFile("file.bmp", wxBITMAP_TYPE_BMP);

C++ declare 'main' as a reference to function?

What if I define main as a reference to function?
#include<iostream>
#include<cstring>
using namespace std;
int main1()
{
cout << "Hello World from main1 function!" << endl;
return 0;
}
int (&main)() = main1;
What will happen? I tested in an online compiler with error "Segmentation fault":
here
And under VC++ 2013 it will create a program crashing at run-time!
A code calling the data of the function pointer as a code will be compiled which will immediately crash on launch.
I would also like an ISO C++ standard quote about this.
The concept will be useful if you want to define either of 2 entry-points depending on some macro like this:
int main1();
int main2();
#ifdef _0_ENTRY
int (&main)() = main1;
#else
int (&main)() = main2;
#endif
That's not a conformant C++ program. C++ requires that (section 3.6.1)
A program shall contain a global function called main
Your program contains a global not-a-function called main, which introduces a name conflict with the main function that is required.
One justification for this would be it allows the hosted environment to, during program startup, make a function call to main. It is not equivalent to the source string main(args) which could be a function call, a function pointer dereference, use of operator() on a function object, or construction of an instance of a type main. Nope, main must be a function.
One additional thing to note is that the C++ Standard never says what the type of main actually is, and prevents you from observing it. So implementations can (and do!) rewrite the signature, for example adding any of int argc, char** argv, char** envp that you have omitted. Clearly it couldn't know to do this for your main1 and main2.
This would be useful if you want to define either of 2 entry-points depending on some macro
No, not really. You should do this:
int main1();
int main2();
#ifdef _0_ENTRY
int main() { return main1(); }
#else
int main() { return main2(); }
#endif
This is soon going to become clearly ill-formed, thanks to the resolution of CWG issue 1886, currently in "tentatively ready" status, which adds, among other things, the following to [basic.start.main]:
A program that declares a variable main at global scope or that
declares the name main with C language linkage (in any namespace) is
ill-formed.
What will happen in practice is highly dependent on the implementation.
In your case your compiler apparently implements that reference as a "pointer in disguise". In addition to that, the pointer has external linkage. I.e. your program exports an external symbol called main, which is actually associated with memory location in data segment occupied by a pointer. The linker, without looking too much into it, records that memory location as the program's entry point.
Later, trying to use that location as an entry point causes segmentation fault. Firstly, there's no meaningful code at that location. Secondly, a mere attempt to pass control to a location inside a data segment might trigger the "data execution protection" mechanisms of your platform.
By doing this you apparently hoped that the reference will get optimized out, i.e. that main will become just another name for main1. In your case it didn't happen. The reference survived as an independent external object.
Looks like you already answered the question about what happens.
As far as why, in your code main is a reference/pointer to a function. That is different than a function. And I would expect a segment fault if the code is calling a pointer instead of a function.

question with longjmp

I want to use longjmp to simulate goto instruction.I have an array DS containing elements of struct types (int , float, bool ,char). I want to jump to the place labled "lablex" where x is DS[TOP].int_val. how can I handle this?
sample code :
...
jmp_buf *bfj;
...
stringstream s;s<<"label"<<DS[TOP].int_val;
bfj = (jmp_buf *) s.str();
longjmp(*bfj,1);
but as I thought it's having problem what should I do?
error:
output.cpp: In function ‘int main()’:
output.cpp:101: error: invalid cast from type ‘std::basic_string, std::allocator >’ to type ‘__jmp_buf_tag (*)[1]’
You probably don't want to use longjmp at all but I hate it when people answer a question with "Why would you want to do that?" As has been pointed out your longjmp() usage is wrong. Here is a simple example of how to use it correctly:
#include <setjmp.h>
#include <iostream>
using namespace std;
jmp_buf jumpBuffer; // Declared globally but could also be in a class.
void a(int count) {
// . . .
cout << "In a(" << count << ") before jump" << endl;
// Calling longjmp() here is OK because it is above setjmp() on the call
// stack.
longjmp(jumpBuffer, count); // setjump() will return count
// . . .
}
void b() {
int count = 0;
cout << "Setting jump point" << endl;
if (setjmp(jumpBuffer) == 9) return;
cout << "After jump point" << endl;
a(count++); // This will loop 10 times.
}
int main(int argc, char *argv[]) {
b();
// Note: You cannot call longjmp() here because it is below the setjmp() call
// on the call stack.
return 0;
}
The problems with your usage of longjmp() are as follows:
You don't call setjmp()
You haven't allocated the jmp_buf either on the stack or dynamically. jmp_buf *bfj is just a pointer.
You cannot cast a char * to jmp_buf * and expect it to work. C++ not a dynamic language it is statically compiled.
But really, it is very unlikely that you should be using longjmp() at all.
The normal way to use longjump is incombination with setjump() as described here. You seem to want to make a jumptable as normally done with switch-case or with virtual functions.
Anyway, labels in code (compile-time) are not reachable with strings (run-time), so that is already your first problem. You would really need to find out the address of where you want to jump to and my best guess would be to put setjump()'s where your labels are.
You've totally failed C++. Firstly, goto's are bad, and not for the uninitiated- there's a reason that for, while, break, continue etc exist. Secondly, you're trying to convert a string into an identifier, which is impossible at runtime unless you code it yourself. Thirdly, you're.. trying to cast a const char* to a jmp_buf*? What?
In addition to that, C++ does have goto. But if you want to jump given an int, then you're going to have to switch it, e.g.
switch (DS[TOP].int_val) {
case 1:
goto label1;
break;
case 2:
goto label2;
break;
default:
throw std::runtime_error("Unrecognized label!");
}
Sounds like you want a function pointer:
((void(*)(void))*((int *)DS[TOP].int_val))();
This treats DS[TOP].int_value like an address and jumps to it. If you wanted to jump to where DS[TOP].int_value is located, you would:
((void(*)(void))*((int *)&DS[TOP].int_val))();
Either way, ugly, ugly code. But it should do what you want.
When setjmp() is called, the system effectively takes a snapshot of the call and parameter stack. This snapshot will remain valid until user code exits the block in which setjmp() was called; if longjmp() is called with that snapshot, execution will resume as though the setjmp() were returning for the first time, except that instead of returning zero, it will return the second parameter passed to longjmp(). It is very important to note that calling longjmp() with an invalid snapshot may have very bad effects. In some systems, such an invalid call may "seem" to work, but corrupt the system in such a way that it later crashes.
Although setjmp()/longjmp() are sometimes appropriate in pure C programs, having a C program call setjmp() to create a snapshot, and then call some C++ code which in turn calls longjmp() to return to that snapshot, is a recipe for disaster. Nearly all situations where one would want to do that may be better handled using exceptions.