Summary:
It doesn't work if you put implementation of inline next_id()
to a single c
file, which means the function is in a single compile unit. So main
cannot find inline next_id()
, you'll get the error undefined reference
.
It can be compiled if you declare inline next_id()
in a shared header file, in which case each compile unit will properly find inline next_id()
.
In my case, only one instance of this global variable will appear in virtual address space .DATA
segment of the process. The output number is continuous.
Example:
Makefile 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
main.cpp 12:
#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;
}
second.hpp 1:
void consume_id();
second.cpp 7:
#include <cstdio>
#include "share.hpp"
void consume_id(){
printf("[scnd] %d\n", next_id());
}
share.hpp 4:
#pragma once
int next_id();
share.cpp 7:
static int _next_id = 0;
int next_id()
{
return _next_id++;
}
Result output:
[main] 0
[scnd] 1
[main] 2
[scnd] 3
[main] 4
But if it is changed to:
share.cpp 4:
inline int next_id()
{
return _next_id++;
}
undefined reference to `next_id()'
If changed to
share.hpp 7:
#pragma once
static int _next_id = 0;
inline int next_id()
{
return _next_id++;
}
Works
EDIT:
It seems to be an undefined behavior
I'm using `gcc version 11.2.0 (Ubuntu 11.2.0-19ubuntu1)
IN MY CASE
You will have copies of static int _next_id
but only in the object file. In memory there is only one.
objdump -d main > main.s
main.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
Here function _Z7next_idv
only appears in memory for 1 time.
main.s 147:
11bb: 8b 05 53 2e 00 00 mov 0x2e53(%rip),%eax # 4014 <_ZL8_next_id>
The label of _next_id
is _ZL8_next_id
, only appears in memory for 1 time as well.