简体   繁体   English

头文件中的`static`,`extern`,`const`

[英]`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: ah将包含多个.cpp文件,我的问题是:

1. x1 is just a declaration, isn't it? 1. x1只是一个声明,不是吗? So its definition should be done in one of those .cpp files, right? 所以它的定义应该在其中一个.cpp文件中完成,对吧?

2. x2 is a definition, right? 2. x2是一个定义,对吗? I used to think that static int is also a declaration just like extern int , but I was wrong. 我以前认为static int也是一个类似于extern int的声明,但我错了。 x2 will only be visible in ah ? x2只会在ah

3. x3 will be defined multiple times if ah is included in multiple .cpp files, so x3 will result in compile-error, right? 3.如果多个.cpp文件中包含ah x3将被定义多次,因此x3将导致编译错误,对吧?

4. x4 is a definition, right? 4. x4是一个定义,对吗?

5.Here in class A, x5 is a declaration, yes. 5.在A级, x5是声明,是的。 But what about x4 ? 但是x4怎么样?

1.x1 is just a declaration, isn't it? 1.x1只是一个声明,不是吗? So its definition should be done in one of those .cpp files, right? 所以它的定义应该在其中一个.cpp文件中完成,对吧?

Correct 正确

2.x2 is a definition, right? 2.x2是一个定义,对吗? I used to think that static int is also a declaration just like extern int, but I was wrong. 我以前认为static int也是一个类似于extern int的声明,但我错了。 x2 will only be visible in ah? x2只会在啊?

A different x2 will be available in each translation unit that includes the header. 每个包含标题的翻译单元将提供不同的x2

3.x3 will be defined multiple times if ah is included in multiple .cpp files, so x3 will result in compile-error, right? 如果多个.cpp文件中包含啊,则将多次定义3.x3,因此x3将导致编译错误,对吧?

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? 4.x4是一个定义,对吗?

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 是的,这是一个定义,但与x2一样,每个翻译单元都有自己的x4 (因为static而且因为它是const意味着内部连接)

5.Here in class A, x5 is a declaration, yes. 5.在A级,x5是声明,是的。 But what about x4? 但是x4怎么样?

Yes, x5 is a declaration only (with initialization). 是的, x5只是一个声明(带初始化)。 The confusion might arise because the keyword static is reused to mean different things in different contexts. 可能会出现混淆,因为关键字static被重用来表示不同上下文中的不同内容。 In x5 it means attribute of the class , while in x4 it means internal linkage x5它表示类的属性 ,而在x4它表示内部链接

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 . 它是唯一的声明(IIRC)声明可以有一个值,原因是它允许编译器在包含该标头的所有转换单元中使用常量的值作为编译时常量 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. 现在的事实是,在大多数情况下,常量不会被使用,因为当使用表达式A::x5时,编译器将替换该值。 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. 因为f的参数是一个引用,所以使用A::x5需要一个左值 (注意,const-ness和lvalue / rvalue-ness几乎是正交的),这需要在单个翻译单元中定义成员。你的计划。

  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 . 它是一个定义, x2将为0,并且包含标题的每个翻译单元都有自己的x2副本。

  3. Yes, but it will result in a linker-error, not compiler. 是的,但它会导致链接器错误,而不是编译器。

  4. Same as 2., but you can't modify it. 与2.相同,但您无法修改它。

  5. Inside a class, static has a different meaning. 在一个类中, static具有不同的含义。 It's legal there just because x5 is of const integral type which is also initialized. 这是合法的,因为x5是const整数类型,也是初始化的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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