Nar*_*ann 5 c++ static-variables inline-functions
我有这个代码:
// my.h
#ifndef MY_HEADER
#define MY_HEADER
int create_uid();
#endif
Run Code Online (Sandbox Code Playgroud)
// my.cpp
#include "my.h"
static int _next_uid = 0;
int create_uid()
{
return _next_uid++;
}
Run Code Online (Sandbox Code Playgroud)
我想内联create_uid(),同时保持_next_uid变量对程序全局,以便变量是唯一的。
我的问题是:
inlinerequire 语句_next_uid在编译单元之外是否可见?注意:这似乎并没有清楚地回答这些问题。
Plu*_*eto -1
概括:
inline next_id()如果将 的实现放在单个c文件中,这意味着该函数位于单个编译单元中,则它不起作用。所以main找不到inline next_id(),你会得到错误undefined reference。
inline next_id()如果在共享头文件中声明它就可以编译,在这种情况下每个编译单元都会正确找到inline next_id(),在这种情况下每个编译单元都会正确找到.
就我而言,该全局变量只有一个实例会出现在.DATA进程的虚拟地址空间段中。输出的数字是连续的。
例子:
生成文件8:
all:
c++ -c main.cpp
c++ -c second.cpp
c++ -c share.cpp
c++ main.o second.o share.o -o main
clean:
rm -f main.o second.o share.o main
Run Code Online (Sandbox Code Playgroud)
主要.cpp 12:
all:
c++ -c main.cpp
c++ -c second.cpp
c++ -c share.cpp
c++ main.o second.o share.o -o main
clean:
rm -f main.o second.o share.o main
Run Code Online (Sandbox Code Playgroud)
第二个.hpp 1:
#include <cstdio>
#include "share.hpp"
#include "second.hpp"
int main(){
printf("[main] %d\n", next_id());
consume_id();
printf("[main] %d\n", next_id());
consume_id();
printf("[main] %d\n", next_id());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第二个.cpp 7:
void consume_id();
Run Code Online (Sandbox Code Playgroud)
分享.hpp 4:
#include <cstdio>
#include "share.hpp"
void consume_id(){
printf("[scnd] %d\n", next_id());
}
Run Code Online (Sandbox Code Playgroud)
分享.cpp 7:
#pragma once
int next_id();
Run Code Online (Sandbox Code Playgroud)
结果输出:
[main] 0
[scnd] 1
[main] 2
[scnd] 3
[main] 4
Run Code Online (Sandbox Code Playgroud)
但如果改成:
分享.cpp 4:
static int _next_id = 0;
int next_id()
{
return _next_id++;
}
Run Code Online (Sandbox Code Playgroud)
对“next_id()”的未定义引用
如果改为
分享.hpp 7:
[main] 0
[scnd] 1
[main] 2
[scnd] 3
[main] 4
Run Code Online (Sandbox Code Playgroud)
作品
编辑:
这似乎是一个未定义的行为
我正在使用 `gcc 版本 11.2.0 (Ubuntu 11.2.0-19ubuntu1)
就我而言
static int _next_id您将拥有但仅在目标文件中的副本。记忆里只有一个。
inline int next_id()
{
return _next_id++;
}
Run Code Online (Sandbox Code Playgroud)
主要.s 143:
00000000000011b3 <_Z7next_idv>:
11b3: f3 0f 1e fa endbr64
11b7: 55 push %rbp
11b8: 48 89 e5 mov %rsp,%rbp
11bb: 8b 05 53 2e 00 00 mov 0x2e53(%rip),%eax # 4014 <_ZL8_next_id>
11c1: 8d 50 01 lea 0x1(%rax),%edx
11c4: 89 15 4a 2e 00 00 mov %edx,0x2e4a(%rip) # 4014 <_ZL8_next_id>
11ca: 5d pop %rbp
11cb: c3 ret
Run Code Online (Sandbox Code Playgroud)
这里的函数_Z7next_idv只在内存中出现1次。
主要.s 147:
11bb: 8b 05 53 2e 00 00 mov 0x2e53(%rip),%eax # 4014 <_ZL8_next_id>
Run Code Online (Sandbox Code Playgroud)
的标签_next_idis _ZL8_next_id,也只在内存中出现 1 次。