Neither case, really. The problem boils down to the article you linked being at best misleading if not incorrect. The article does not actually say that "generating storage" is a necessary consequence of either but it misleadingly implies it. It's poorly worded, and very imprecise, I think.
Unfortunately the standards aren't very easy to read either, see section 3.1: [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf][1]
In a nutshell, for structure definitions, a declaration just introduces the type name or structure tag "widget". The definition is a declaration that also provides the body which "defines" the type, like the first example.
The examples from the C++ standard are easier to understand:
Example: all but one of the following are definitions:
int a; // defines a
extern const int c = 1; // defines c
int f(int x) { return x+a; } // defines f and defines x
struct S { int a; int b; }; // defines S, S::a, and S::b
struct X { // defines X
int x; // defines non-static data member x
static int y; // declares static data member y
X(): x(0) { } // defines a constructor of X
};
int X::y = 1; // defines X::y
enum { up, down }; // defines up and down
namespace N { int d; } // defines N and N::d
namespace N1 = N; // defines N1
X anX; // defines anX
whereas these are just declarations:
extern int a; // declares a
extern const int c; // declares c
int f(int); // declares f
struct S; // declares S
typedef int Int; // declares Int
extern X anotherX; // declares anotherX
using N::d; // declares d
You can "define" a structure which does nothing but define it's layout. But you can also "define" a variable of that structure type. That is when storage might be "generated" (I would maybe say allocated or reserved). When a global variable of the structure type is defined it would result in the binary executable containing a chunk of data the size of the structure. If a local (automatic or stack) variable is defined, it would take up space on the execution stack instead at runtime.
For example, if global (i.e. not in a function):
struct widget x; // defines variable x of type struct widget
// which must be defined somewhere prior
struct widget2; // declares structure widget2
// does nothing except tells the compiler there will be some
// structure definition named widget2 coming later
int fn(widget2 *p); // OK widget2 need only be *declared* first
// NO
// struct widget2 y; // illegal - has not be defined yet
struct widget2 // defines structure widget2 that *would* take up ~8 bytes
{
int thing1;
int thing2;
} y; // defines variable y of type struct widget2 that *does* take up ~8 bytes
struct widget2 z[10]; // defines global variable z that *does* take up ~80 bytes
Maybe another way to look at it is that defining a type is fundamentally different than defining a variable. A type is a concept that exists at compile time and does not take up space at runtime (RTTI ignored).
The C and C++ standards are making the distinction between declare and define because, amongst other reasons, you can not have more than one different definition of something, but you can declare it many times. For variables, definitions roughly coincide with storage allocation, but that isn't the main reason for the distinction.
widget. Are you sure thatstruct widget{...};is a definition in C++? I would have thought it's also a declaration.struct widget {...};is both a definition and declaration in C++ (and probably C). All definitions are also declarations, but not the other way around.