加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 06:00:30 所属栏目:百科 来源:网络整理
导读:有没有办法通过链接其.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 iostreamint x;int main(){
有没有办法通过链接其.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到最终的程序,你结束具有更多的功能.我被告知大多数编译器将无条件地初始化所有全局变量,因为不这样做会打破很多现实世界的代码.但不要依赖它!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读