1

The code below compiles just fine (unless the call to method is uncommented).

  1. Why is it allowed to "call" to the default constructor? (there shouldn't be one)
  2. Why is the declaration of the member function not an error?

.

extern "C"
{
    struct S
    {
        int some_int;
        void method(){}
    };
}

int main()
{
    S s();
//    s.method();
    return 0;
}
François Andrieux
  • 28,148
  • 6
  • 56
  • 87
Danish
  • 407
  • 3
  • 10

2 Answers2

6

First, S s(); declares a function named s that takes no arguments and returns an object of type S. Just like int f();.

Second, that extern "C" isn't relevant here. It's used, roughly, for functions that are written in C and called from C++. It doesn't mean "pretend that this code is C code".

Third, S does have a default constructor. The compiler generates one. In this case it doesn't do anything, because there are no members of S that require non-trivial initialization. To use the default constructor you'd write S s; or S s{};.

Fourth, the reason that declaring a member function is okay is that a struct and a class in C++ can have member functions. I know, that sounds tautologous, but it's important to keep in mind that a struct can have member functions, static data, private, protected, and public members just like a class. The only differences between a struct and a class is that by default members of a class are private while members of a struct are public, and by default a base of a class is inherited privately while a base of a struct is inherited publicly.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • `-Wvexing-parse` or just `-Wall` flag can catch the accidental function declarations with clang. – Waqar Aug 10 '20 at 14:07
  • @Waqar -- this is **not** the ["most vexing parse"](https://en.wikipedia.org/wiki/Most_vexing_parse). I sure hope that some busybody compiler won't insist on telling me that `S s();` might be a mistake. That would make function declarations useless. – Pete Becker Aug 10 '20 at 14:09
  • For the code provided by OP, [clang](https://godbolt.org/z/T3WsWE) does give that warning. But only for the things inside a function scope not in a global or namespace scope. – Waqar Aug 10 '20 at 14:17
-1

Adding a default constructor (although it's optional here) and using curly-braces rather than parenthesis or you don't even need to use that, will solve your issue:

....
struct S {
    S() {} // declaring the constructor explicitly here
};
....

int main(void) {
    S s{}; // Don't use s() - a function, instead, call the
           // default constructor
//  S s;
    s.method();

    return 0;
}
Rohan Bari
  • 7,482
  • 3
  • 14
  • 34