Define main function in class [duplicate] - c++

This question already has answers here:
in c++ main function is the entry point to program how i can change it to an other function?
(13 answers)
Closed 8 years ago.
I was wondering if its possible to define main() inside a class, something like:
struct runtime_entry_point
{
friend int main()
{
}
};
I have tested that and it doesn't work (Almost in GCC 4.8.2):
g++ -o dist/Release/GNU-Linux-x86/turbo build/Release/GNU-Linux-x86/main.o
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../lib/crt1.o:
In function `_start': collect2: error: ld exited with status 1
This sounds to me like a no definition of main() error.
Later, I have written main in the classic way:
struct runtime_entry_point
{
friend int main()
{
}
};
int main(){}
Now the compilation fails because int main() was already defined inside the struct runtime_entry_point! Whats happening here?

Trivially it is not possible to write main as a part of a class/struct. The linker by default searches for a free main method and links against it, makes it the entry point. You may alter this behavior by at the linker level, in which case main must be a static method in class/struct. But this is linker implementation dependent, not-portable and dangerous.
However, in the second situation you mentioned is a result of violation of One Definition Rule. You are defining a name (main()) more than once in a single translation unit.

Аccording to the article on cppreference.com, the following construction:
struct runtime_entry_point
{
friend int main()
{
}
};
Defines a non-member function, and makes it a friend of this class at the same time. Such non-member function is always inline.
Linker couldn't find main() in object file (inline function), and you can't declare another main() in the same translation unit (as it already declared).

You can not define a function twice, it works when you change the definition into a declaration inside the class/struct:
#include <iostream>
struct runtime_entry_point
{
friend int main();
};
int main()
{
std::cout << "Hello, world!" << std::endl;
}
This works just fine with GCC.

Related

What all are considered in the Class scope?

Just trying to grab the concept revolving around the scope of the Class in C++. If we take an example something like:
#include <iostream>
using namespace std;
string barValue="OUTSIDE CLASS";
class foo
{
public:
void print_bar()
{
cout<<barValue<<endl;
}
};
int main()
{
foo f;
f.print_bar();
return 0;
}
I am wondering:
Is the barValue variable is in the Class scope?
Can the barValue be accepted even if it is defined in one of the included files?
Is the file and all the included files can be called as the scope of the foo Class?
I can understand that the barValue will not be considered if it is defined after the Class body. To follow up is that means all the included files comes before the Class body and in general before the current file content?
Question 1
Is the barValue variable is in the class scope?
barValue is a global variable since you have defined it outside any function and class. Therefore barValue can be used inside the class as you did.
Question 2
Can the barValue be accepted even if it is defined in one of the included files?
Yes even if barValue is defined in a header file it can be used in other files because/if it has external linkage as shown in the below example.
file.h
int barvalue = 34;//barvalue has external linkage
main.cpp
#include <iostream>
#include "file.h"
int main()
{
std::cout<<barvalue<<std::endl;//prints 34
return 0;
}
Question 3
Is the file and all the included files can be called as the scope of the foo class?
No
Question 4
I can understand that the barValue will not be considered if it is defined after the class body. To follow up is that means all the included files comes before the Class body and in general before the current file content?
You should clarify this question more because i think it is not clear what your are asking here but i will try to answer what i understand from your question.
If you define barValue after the class foo definition then the program will not work because since you have defined it after the class definition, therefore it has not been defined/declared at the point when you write cout<<barValue<<endl; which is what the error says as shown below:
#include <iostream>
using namespace std;
class foo
{
public:
void print_bar()
{
cout<<barValue<<endl;//error: ‘barValue’ was not declared in this scope
}
};
int main()
{
foo f;
f.print_bar();
return 0;
}
string barValue="OUTSIDE CLASS";

C++ - how to forward declare a class in the same file as main() - getting variable uses undefined class error

I'm aware of using function prototypes, and I was under the impression that forward class declarations could serve a similar purpose when main() and a class are in the same file. For example, I would have expected this would compile:
// main.cpp
#include <iostream>
// class prototypes
class MyClass;
int main(void)
{
MyClass myClass;
// do stuff with myClass here
return(0);
}
class MyClass
{
public:
int someInt;
double someDouble;
// more stuff here . . .
};
But on the MyClass myClass; line I'm getting the error 'myClass' uses undefined class 'MyClass'. What am I doing wrong?
P.S. I'm aware that I could cut/paste main() below all the classes it uses and that would fix the error, but I'd prefer to keep main() as the first function or class.
P.P.S. I'm aware that in any substantial size production program main(), .h content, and .cpp content would be in 3 separate files. In this case I'm attempting to write a small example or test program where main and a class(es) are in the same file.
Forward declarations can only be used via pointers or references.
Calling a constructor function doesn't fall into this category.
I'm aware that I could cut/paste main() below all the classes it uses and that would fix the error, but I'd prefer to keep main() as the first function or class.
That's why usually header files are used, instead of placing all the declarations and definitions in the main.cpp file.
I'm aware that in any substantial size production program main(), .h content, and .cpp content would be in 3 separate files. In this case I'm attempting to write a small example or test program where main and a class(es) are in the same file.
You should still stick to that idiom though, everything else would probably end up in a mess.
This doesn't use forward declarations but it partially addresses the spirit of a single main.cpp with your "main" at the top. I find this technique sometimes useful when you want to share something via an online C++ ide where a single file is much easier to deal with, and you want to focus on the action in main rather than implementation detail in helper structs/classes etc.
#include <iostream>
template<typename MyClass,typename MyOtherClass>
int main_()
{
MyClass a;
a.do_foo();
MyOtherClass b;
b.do_bar();
return 0;
}
struct MyClass
{
void do_foo() { std::cout << "MyClass: do_foo called\n"; }
};
struct MyOtherClass
{
void do_bar() { std::cout << "MyOtherClass: do_bar called\n"; }
};
int main()
{
return main_<MyClass,MyOtherClass>();
}

Why does a member function exist only once even defined in one multiple included .h file? [duplicate]

This question already has answers here:
How can a C++ header file include implementation?
(7 answers)
Closed 6 years ago.
I am just wondering how the compiler can handle the situation where a member function is declared & defined only in a include file but this .h file is included multiple times in different source codes without complains of the linker regarding multiple definition of ....
foo_1.h:
class foo
{
public:
auto in_include() -> void { printf( "in in_include()\n" ); }
foo();
};
foo_1.cpp:
#include <stdio.h>
#include "foo_1.h"
foo::foo()
{
printf( "in foo()\n" );
in_include();
}
and finally foo_main.cpp:
#include <stdio.h>
#include "foo_1.h"
int main()
{
foo fooObject;
}
These MCVE compiles and links fine and produces the expected output:
in foo()
in in_include()
BUT, when I add in foo_1.h this line int globar_var; then the linker complains [as I expect it]:
/tmp/ccfjJJAT.o:(.bss+0x0): multiple definition of `globar_var'
/tmp/cciob9sM.o:(.bss+0x0): first defined here
I do not consider as a duplicate because I ask why the linker does not complain. The other question is more or less asking why a function can be defined in a header file.
Class member functions that are defined with a body within the class declaration automatically become inline functions, and therefore it's OK even if the definition is compiled multiple times. You can get the same for non-class functions by using the inline keyword.
How this is implemented in practice is up to the compiler - it could actually inline the code every time it's called (think copy and paste), or it could arrange for some linker magic I don't fully understand to happen that prevents the collision.

Compilation failed, c++ program with static variable as private member variable [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
undefined reference to static member variable
What is an undefined reference/unresolved external symbol error and how do I fix it?
#include<iostream>
using namespace std;
class abc {
private:
static int a ;
public:
abc(int x) {
a = x;
}
void showData() {
cout<<"A = "<<a<<endl;
}
};
int main() {
abc a1(4);
abc a2(5);
a1.showData();
a2.showData();
return 0;
}
When I try to compile this function on Ubuntu with GCC compiler. I get the following error.
/tmp/ccCKK2YN.o: In function `main':
static1.cpp:(.text+0xb): undefined reference to `Something::s_nValue'
static1.cpp:(.text+0x14): undefined reference to `Something::s_nValue'
collect2: ld returned 1 exit status
Compilation failed.
Where as the following code runs fine
#include<iostream>
using namespace std;
class Something
{
public:
static int s_nValue;
};
int Something::s_nValue = 1;
int main()
{
Something cFirst;
cFirst.s_nValue = 2;
Something cSecond;
std::cout << cSecond.s_nValue;
return 0;
}
Is this because Static member variables needs to initialized explicitly before accessing them via objects.Why so ?
static int s_nValue; doesn't allocate any storage to store the int, it just declares it.
You allocate somewhere in memory to store the variable with:
int Something::a=0;
The declaration of a static data member in the member list of a class is not a definition. You must define the static member outside of the class declaration, in namespace scope.
See this thread.
In short, the static member needs to be initialized somewhere in a .cpp file so that the compiler allocates space for it. The declaration would look like this:
int abc::a = 0;
That happens because since static members are shared between all instances of a class, they need to be declared in one single place.
If you define the static variable inside the class declaration then each include to that file would have a definition to that variable (which is against to the static meaning).
Because of that you have to define the static members in the .cpp.

From where does the compiler start reading

This is a small program :
#include <iostream>
using namespace std;
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
The error that i get here is :error C3861: 'f': identifier not found
If i place the function f above main I will get the desired output.
Why it is so ?
I was told that program execution begins at main. According to this the code should run in the first case also.
How does the compiler start reading the program?
The beginning of the compilation and the beginning of the execution of the program are two different things.
The execution starts from the main.
The compilation begins from the beginning of the file; the compiler don't "jump around" the file to find the needed pieces, but it reads the input in a linear fashion (I suspect that this related, among the other things, to the fact that the C++ grammar is really complicated).
When the compiler is at some point in parsing the file, it only knows what has been declared/defined up to that point1.
Because of this, function prototypes (and non-defining declarations in general) have been invented: the prototypes of all the functions defined in the file are put at the beginning of the file, typically after the #include directives or in a separated include file. The prototypes tell to the compiler that such functions will be defined later, and what is the function signature (i.e. name, parameters, return value).
The prototype is made as a normal function, but without the body, which is replaced by a semicolon2. For example, in your code you would write
void f();
before the main.
IIRC there are some relaxations to this rule that allow the compiler to "wait" for some declarations to make some template magic work, but this is not relevant here.
In a prototype is also common not to write the names of the parameters, leaving just their type (this can be done also in function definitions, but it doesn't make much sense there unless you have a formal parameter you don't use). Still, I prefer to leave the parameter names there as a form of documentation.
I was told that program execution begins at main.
And that's exactly the point.
The compiler starts from main, and then sees a call to f(), which it has not encountered so far (as it is defined afterwards), so it does not know what to do with it.
If you want to define f after main you can place a function prototype before, such as
#include <iostream>
using namespace std;
void f(); // <--- This tells the compiler that a function name f will be defined
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
To be able to call a function it must have been declared at some earlier point in the code. This is just a rule of the language designed to help compilers.
You can declare the function earlier with e.g.
void f();
...and then define it after main as you have done.
The compiler starts at the top and reads down to the bottom.
you'll need to have something like:
#include <iostream>
using namespace std;
void f();
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
No, the compiler needs to see at least a declaration of f() before it is used. A c(++) code file is a simple text file and must be read from begin to end by the compiler.
During the compilation process, when the compiler is evaluating main() it needs to know what f() is in advance to be able to generate the correct assembly code to call this function. That's why you need to put it before main() in this case.
As an alternative you can declare the prototype of f() before main() so the compiler knows it's a local function declared somewhere else on your file:
void f(); // prototype
int main()
{
// .. code ..
}
void f() // implementation of f()
{
// .. code ..
}