Reputation: 2216
This question states that main can be implementation defined with some restrictions.
So, I wrote the following C++
code to try out the following signature of main
:
main.h
class MyClass {
private:
int i;
public:
MyClass();
inline int geti() {
return i;
}
inline void seti(int i) {
this->i = i;
}
~MyClass();
};
MyClass::MyClass() {
this->i = 2;
}
MyClass::~MyClass() {
}
main.c++
#include <iostream>
#include "main.h"
int main(MyClass myClass) {
std::cout << myClass.geti() << std::endl;
return 0;
}
Which Gives the following results:
The command g++ -o main main.c++ -O3
compiles successfully with warnings:
main.c++:5:5: warning: first argument of ‘int main(MyClass)’ should be ‘int’ [-Wmain]
5 | int main(MyClass myClass) {
| ^~~~
main.c++:5:5: warning: ‘int main(MyClass)’ takes only zero or two arguments [-Wmain]
The command clang++ -o main main.c++ -std=c++14
gives the error:
main.c++:5:5: error: first parameter of 'main' (argument count) must be of type 'int'
int main(MyClass myClass) {
^
1 error generated.
the main
file generated by g++
gives SIGSEGV
(why though?)
So, if main can be implementation defined, why does clang
give an error while g++
generated file give SIGSEGV
?
I also went further and created a different code so that I will be able to pass a MyClass
object to main.c++
as follows:
#include <iostream>
#include "main.h"
#include <unistd.h>
int main() {
MyClass myClass;
execve("./main",myClass,NULL);
return 0;
}
However, as execve
takes the second parameter to be a char* const *
, it does not compile. How do I pass the myClass object to the main
file generated by g++
?
Upvotes: 0
Views: 94
Reputation: 119877
The command
g++ -o main main.c++ -O3
compiles successfully with warnings
This is not successful compilation. You should always use -Werror
. If you fail to do so and then decide to ignore the warning and proceed with running the program, it's your own responsibility. You better know full well what you are doing. See this for more information.
the main file generated by g++ gives SIGSEGV (why though?)
The compiler has warned you. It is in your best interest to listen to it. If things go boom, chances are, that's because you have ignored warnings.
why does clang give an error while g++ generated file give SIGSEGV?
The program is not a valid C++ program. There is no meaningful difference between a warning and an error.
How do I pass the myClass object to the main file generated by g++?
You cannot. main
must have a form equivalent to one of these two:
int main()
int main(int argc, char* argv[])
(Optional reading in italics) Other forms of main
are implementation-defined. This means your implementation needs to support them in a documented way. Unless you have read documentation for your implementation and found that it supports the form of main
you want, there's no way to do that.
Other than having an implementation-defined main
, the only way a program can get hold of an object of a class type is by constructing that object.
Upvotes: 1
Reputation: 84561
You are close. You have identified your primary issue attempting to pass as a parameter to main()
-- that won't work. The declaration for main()
is defined by the standard and you are limited to passing string values (nul-terminated character arrays... C-Strings) in as arguments.
In your case you need to create an instance of your class within main()
, e.g.
#include <iostream>
#include "main.h"
int main() {
MyClass myClass;
std::cout << myClass.geti() << std::endl;
return 0;
}
Your main.h
header has a variable shadowing problem where at line 10:
inline void seti(int i) {
int i
shadows a prior declaration at line 3, e.g. int i;
(though the consequence would be unlikely to matter). Just replace the variable name in the second declaration with j
(or whatever you like). Your code will compile without warning, e.g.
class MyClass {
private:
int i;
public:
MyClass();
inline int geti() {
return i;
}
inline void seti(int j) {
this->i = j;
}
~MyClass();
};
MyClass::MyClass() {
this->i = 2;
}
MyClass::~MyClass() {
}
Example Use/Output
$ ./bin/main
2
You can also call your seti()
function to update the private variable in your class, e.g.
myClass.seti(5);
std::cout << myClass.geti() << std::endl;
Which would now output 5
.
Let me know if you have further questions.
Upvotes: 1