0

So I have this problem for a while now. I just couldn't find the answer to the question. Why do I have to give the data type twice while using static variables inside a class?

Here's an example:

#include <iostream>

class Test{
public:
static int test;
};

//right here is the point of confusion
int Test::test = 10;


int main(){
Test test;
std::cout << test.test << "\n";
}

As you can see from my program above I had to initialize the variable this way. But what about the duplicate data type specification? Why did I have to write the "int" data type twice? Once already in the class and then again? What is the underlying reason? Thanks for any help in advance.

12
  • 1
  • 1
    @JasonLiam Got any links to related SO posts? I think it's an interesting question, and I haven't seen it being discussed before. Commented Oct 14, 2022 at 10:57
  • 1
    @JasonLiam I don't see how the dupe is related. OP doesn't ask why a definition is needed, but why the grammar for it requires spelling a type the second time. Commented Oct 14, 2022 at 10:59
  • 1
    @JasonLiam Yes, they have to have the same type, but I have no idea why you're required to spell the type in the definition at all, if it could be inferred from the declaration. Other than simplifying the grammar. Commented Oct 14, 2022 at 11:02
  • 1
    @JasonLiam I know how this works. "You must include int while definning it also" Yes, and OP asks why, if the type should be known from the declaration. Yes, allowing the type to be omitted would require a different grammar. Commented Oct 14, 2022 at 11:06

3 Answers 3

2

You don't 'have to' duplicate as long as you provide the type somehow. Grammar requires a type there that cannot be auto (which is not type, but usually people expect to be able to write it in place of a type), but you can still let the compiler deduce it:

    #include <iostream>
     
    class Test{
    public:
        static int test;
    };
     
    //right here is the point of confusion
    decltype(Test::test) Test::test = 10;
     
     
    int main(){
        Test test;
        std::cout << test.test << "\n";
    }

If you don't like duplicating type name, you might write a macro for it.

6
  • This doesn't answer the question. The question is why it is required at all and not how to workaround it. Why can't we omit decltype(Test::test) and int when defining the static data member. Commented Oct 14, 2022 at 11:09
  • @JasonLiam I wrote, 'grammar requires'. You wrote the details of the grammar, but the main cause is that grammar requires user to write it. And there's absolutely no further reason - you could define a grammar where @def simbolizes it. But C++ is not that grammar - so I think I answered it.
    – lorro
    Commented Oct 14, 2022 at 11:43
  • I see but note that there is still duplication in your example. We still have to write Test::test inside the decltype. OP seems to be asking why we can't omit it(the int part and the decltype(Test::test) part completely. Basically, because the grammar requires it. Commented Oct 14, 2022 at 11:47
  • @JasonLiam Please read my answer before trying to find an error in it. I've explained: if you don't like duplicating name, you might write a macro for it. DEF(Test::Test) = 10; has no duplication and it's trivial to define.
    – lorro
    Commented Oct 14, 2022 at 11:53
  • It's not that I don't like the duplicated name. My problem with your answer was that you've written in the first line of your answer "you don't have to" which is wrong. Because we still need provide a type. Now whether we do it by directly writing int or decltype(Test::test) is irrelevant. If you were to clarify that quoted statement like by changing it to something like "You don't have to write int explicitly as you can also write decltype(Test::test) but anyhow the type must be provided" then your answer will be more clear. Commented Oct 14, 2022 at 12:03
1

Why did I have to write the "int" data type twice?

Because there are 3 components of a simple-declaration, namely attributes, specifiers and declarators and a definition(like the one you provided) is also a declaration so it has to follow these rules. Now, the second of these component, specifier indicate the type, storage class or other properties of the entity that is being declared and is not optional.

This means that when providing the definition for the static data member, you still need to provide the type-specifier according to the grammar. This also means that you can use decltype(Test::test) instead of int when defining the static data member outside the class.

The point is that the current grammar requires us to specify the type when defining.

1
  • Thank you! That cleared all doubt!
    – Noname
    Commented Oct 14, 2022 at 11:58
0

If you are asking about the rationale, then nobody (except probably Bjarne himself) knows for sure. Such things were rarely publicly discussed or written down when the language was conceived. But if I had to guess, I'd say that it is to make the language rules simple and get the language out of the door faster. Every declaration needs a type. That's essential in the formulation of the grammar. If you change such a fundamental thing willy-nilly, you risk opening a huge can of worms.

1
  • Yeah exactly.. I was wondering about that. Probably I'll never know..
    – Noname
    Commented Oct 14, 2022 at 15:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.