简体   繁体   中英

`static`, `extern`, `const` in header file

//a.h

extern int x1;
static int x2;
int x3;
static const int x4;

class A {
    public:
        static const int x5 = 10;
};

ah will be included by multiple .cpp files, my question is:

1. x1 is just a declaration, isn't it? So its definition should be done in one of those .cpp files, right?

2. x2 is a definition, right? I used to think that static int is also a declaration just like extern int , but I was wrong. x2 will only be visible in ah ?

3. x3 will be defined multiple times if ah is included in multiple .cpp files, so x3 will result in compile-error, right?

4. x4 is a definition, right?

5.Here in class A, x5 is a declaration, yes. But what about x4 ?

1.x1 is just a declaration, isn't it? So its definition should be done in one of those .cpp files, right?

Correct

2.x2 is a definition, right? I used to think that static int is also a declaration just like extern int, but I was wrong. x2 will only be visible in ah?

A different x2 will be available in each translation unit that includes the header.

3.x3 will be defined multiple times if ah is included in multiple .cpp files, so x3 will result in compile-error, right?

More precisely it will result in a linker error. The compiler processes each translation unit, the linker binds them together and detects that the symbol is defined multiple times.

4.x4 is a definition, right?

Yes, it is a definition, but as with x2 each translation unit will have it's own x4 (both because of static and because it is const which implies internal linkage

5.Here in class A, x5 is a declaration, yes. But what about x4?

Yes, x5 is a declaration only (with initialization). The confusion might arise because the keyword static is reused to mean different things in different contexts. In x5 it means attribute of the class , while in x4 it means internal linkage

This last case is special. It is the only declaration (IIRC) where the declaration can have a value, and the reason is that it allows the compiler to use the value of the constant in all translation units that include that header as a compile time constant . If the value had to be provided with the definition, then only a single translation unit would have access to that value. The definition of that static member would be:

const int A::x5; // no initialization here

And you must provide one if the member is odr-used . Now the fact is that in most cases the constant will not be odr-used as the compiler will substitute the value when the expression A::x5 is used. Only when the member is used as an lvalue you need the definition, for example:

void f( const int & ) {}
int main() {
   f( A::x5 );
}

Because the argument to f is a reference, the use of A::x5 requires an lvalue (note, const-ness and lvalue/rvalue-ness are almost orthogonal), and that requires the definition of the member in a single translation unit in your program.

  1. correct

  2. It is a definition, x2 will be 0, and every translation unit that contains the header will have its own copy of x2 .

  3. Yes, but it will result in a linker-error, not compiler.

  4. Same as 2., but you can't modify it.

  5. Inside a class, static has a different meaning. It's legal there just because x5 is of const integral type which is also initialized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM