kesarling
kesarling

Reputation: 2216

Where is the syntax with class as a parameter in main needed?

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

Answers (2)

n. m. could be an AI
n. m. could be an AI

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

David C. Rankin
David C. Rankin

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

Related Questions