0

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++?

kesarling He-Him
  • 1,944
  • 3
  • 14
  • 39

2 Answers2

1

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.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Thanks for the answer a lot. But I think you've missed the question (I know my English is terrible). The question is not just about `SIGSEGV` Its about what is meant by user defined implementation of main function. You see, if the main function can be implementation defined, why generate warning when the main is not standard (or worse, error in case of `clang`)? – kesarling He-Him Jun 07 '20 at 11:59
  • But that is the point. The only time `main()` can be defined differently from either `int main (void)` or `int main (int argc, char **argv)` is if you are operating in a *Freestanding* environment without any operating system. Then `main()` can be implementation defined. If you are not in a *Freestanding* environment, you are stuck with the standard definitions of `main()`. Now there are a few `ctor` and `dtor` function to main you can define to run before (and after) `main()` is invoked, but is that what you are asking here? – David C. Rankin Jun 07 '20 at 12:03
  • That is the reason you get the error `"error: first parameter of 'main' (argument count) must be of type 'int'"` – David C. Rankin Jun 07 '20 at 12:05
  • RE: "Now there are a few ctor and dtor function to main you can define to run before (and after) main() is invoked, but is that what you are asking here" yes that is what I essentially want to ask :) – kesarling He-Him Jun 07 '20 at 12:11
  • Here is an old post on the subject [How exactly does __attribute__((constructor)) work?](https://stackoverflow.com/questions/2053029/how-exactly-does-attribute-constructor-work/24361145?r=SearchResults&s=1|73.5756#24361145) That is just the basics, but provides how to approach them. – David C. Rankin Jun 07 '20 at 13:19
1

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.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243