SIOF

SIOF 是static initialization order fiasco的缩写,涉及的问题为初始化顺序;

下面为 stack overflow 中 Hans Passant 的解释:

SIOF is very much a runtime artifact, the compiler and linker don't have much to do with it. Consider the atexit() function, it registers functions to be called at program exit. Many CRT implementations have something similar for program initialization, let's call it atinit().

Initializing these global variables requires executing code, the value cannot be determined by the compiler. So the compiler generates snippets of machine code that execute the expression and assigns the value. These snippets need to be executed before main() runs.

That's where atinit() comes into play. A common CRT implementation walks a list of atinit function pointers and execute the initialization snippets, in order. The problem is the order in which the functions are registered in the atinit() list. While atexit() has a well defined LIFO order, and it is implicitly determined by the order in which the code calls atexit(), such is not the case for atinit functions. The language specification doesn't require an order, there is nothing you could do in your code to specify an order. SIOF is the result.

One possible implementation is the compiler emitting function pointers in a separate section. The linker merges them, producing the atinit list. If your compiler does that then the initialization order will be determined by the order in which you link the object files. Look at the map file, you should see the atinit section if your compiler does this. It won't be called atinit, but some kind of name with "init" is likely. Taking a look at the CRT source code that calls main() should give insight as well.

使用代码测试:
file1.cpp

extern int x;
int y = x + 1;


file2.cpp

extern int y;
int x = y + 1;

main.cpp

#include <stdio.h>
#include <stdlib.h>

extern int x;
extern int y;

int main()
{
    printf("x : %d, y : %d\n", x, y);
    return 0;
}

liuzebo@ubuntu:/mnt/hgfs/Workspace/SnippetTest/siof$ g++ main.o file1.o file2.o -o main
liuzebo@ubuntu:/mnt/hgfs/Workspace/SnippetTest/siof$ ./main
x : 2, y : 1
liuzebo@ubuntu:/mnt/hgfs/Workspace/SnippetTest/siof$ g++ main.o file2.o file1.o -o main
liuzebo@ubuntu:/mnt/hgfs/Workspace/SnippetTest/siof$ ./main
x : 1, y : 2


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值