Let’s put function declaration/definition aside — simpler.
Let’s put aside local static/non-static variables — different story.
Let’s put aside function parameters. They are like local variables.
The word “static” is heavily overloaded and confusing. I will try to avoid it as far as possible.
The tricky/confusing categories are
- category: static field. Most complex and better discussed in a dedicated post — See https://bintanvictor.wordpress.com/2017/02/07/c-static-field-init-basic-rules/
- category: file-scope var — i.e. those non-local vars with “static” modifier
- category: global var declaration — using “extern”
- definition of the same var — without “extern” or “static”
- category: non-static class field, same as the classic C struct field <– the main topic in the post. This one is not about declaration/definition of a variable with storage. Instead, this is defining a type!
I assume you can tell a variable declaration vs a variable definition. Our intuition is usually right.
The Aha —  pointed out — A struct field listing is merely describing what constitutes a struct type, without actually declaring the existence of any variables, anything to be constructed in memory, anything addressable. Therefore, this listing is more like a integer variable declaration than a definition!
Q: So when is the memory allocated for this field?
A: when you allocate memory for an instance of this struct. The instance then becomes an object in memory. The field also becomes a sub-object.
Main purpose to keep struct definition in header — compiler need to calculate size of the struct.
Completely different purpose from function or object declarations in headers. Scott Meyers discussed this in-depth along with class fwd declaration and pimpl.
-  P45 [[c++primer]]
-  http://stackoverflow.com/questions/28517555/c-declaration-of-class-variables-in-header-or-cpp