C 11链接上的调用寄存器功能?

前端之家收集整理的这篇文章主要介绍了C 11链接上的调用寄存器功能?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有没有办法通过链接其.o文件调用函数

例如:

Foo.cpp中:

extern int x;

void f() { x = 42; }

struct T { T() { f(); } } t; // we use constructor of global
                             // object to call f during initialization

bar.cpp:

#include <iostream>

int x;

int main()
{
    std::cout << x;
}

要编译/链接/运行:

$g++ -c foo.cpp
$g++ -c bar.cpp
$g++ foo.o bar.o
$./a.out
42

这似乎与gcc 4.7一起使用.它按预期输出42.但是我记得一些旧的编译器,我有一个这个模式的问题,因为没有什么是真正的“使用”foo.o它被优化在链接时间. (也许这个特定的例子不是由于某种原因代表问题)

C11标准对这种模式有什么看法?保证工作吗?

解决方法

我相信你没有脱钩.该标准不能保证您的代码按照预期的方式工作,尽管许多人依赖这种行为进行各种“自我注册”的构造.

您的对象t被动态初始化,这具有调用f的副作用.这个标准有关静态存储对象的动态初始化的说明(3.6.2 / 4,“非局部变量的初始化”):

It is implementation-defined whether the dynamic initialization of a non-local variable with static storage
duration is done before the first statement of main. If the initialization is deferred to some point in time
after the first statement of main,it shall occur before the first odr-use (3.2) of any function or variable
defined in the same translation unit as the variable to be initialized.

在你的代码中,只有x是odr使用的,但是x在主要的翻译单元中定义.程序中没有使用其他TU的变量或函数,所以在技术上不能保证t将被初始化.从技术上讲,每个TU的内容必须由程序的静态控制流程引用,以便初始化所有内容.

正如我所说,有很多真实世界的代码,有“自我注册”翻译单位(例如,在字符串键映射中注册一个工厂函数指针),以便通过简单地添加TU到最终的程序,你结束具有更多的功能.我被告知大多数编译器将无条件地初始化所有全局变量,因为不这样做会打破很多现实世界的代码.但不要依赖它!

猜你在找的C&C++相关文章