Attribute函数(__attribute((constructor)) 在执行程序里失效,没有被调用,手动调用)

2024-06-06 14:50:05 :22

attribute函数(__attribute((constructor)) 在执行程序里失效,没有被调用,手动调用)

这篇文章给大家聊聊关于attribute函数,以及__attribute((constructor)) 在执行程序里失效,没有被调用,手动调用对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。

本文目录

__attribute((constructor)) 在执行程序里失效,没有被调用,手动调用

利用 gcc 提供的 __attribute((constructor)) 可以在 main() 之前就可做一些初始化的工作, 但是在嵌入式上用却出了点问题. 用 __attribute((constructor)) 定义的函数在动态库是可以被程序正常调用的, 但是放在main() 一起编译就没被调用, 在host PC上同样的程序却可以被正常的调用 在上面的例子中, 在 目标板子上编译出来跑起, test()没有被执行, 但是 pc是可以的. 太奇怪了,动态库却没有这样的问题. 查看 汇编test也被编译进.o了,编译成可执行文件 .init_array 也是存在的, 但是就是没有被调用. 对比目标板子编出来和pc端的执行文件的elf布局,发现还是有些区别, 在pc端的有__init_array_start 和  __init_array_end 这两个符号, 但目标板子 却没有.当在目标板子手动调用__init_array_start 后, 没有报错, 重新查看elf, 出现了 __init_array_start ,但是没有 __init_array_end. 说明gcc对这个还是有处理的, 时间关系最后手动调用 通过 __init_array_start 和 __init_array_end 来执行init_array段的 __attribute((constructor))  的函数.

关于__attribute__((deprecated))的作用

  gcc __attribute__ ((deprecated)),可以修饰函数或是某个个变量,对函数表明此函数属性指示存在某个函数,但如果使用这个不提倡使用的函数,编译器必须生成警告;对变量表明可以使用 deprecated 变量属性声明不提倡使用的变量,而不会导致编译器发出任何警告或错误。但是,对 deprecated 变量的任何访问都会生成警告,但仍会进行编译。警告指出了使用和定义变量的位置。这有助于确定不提倡使用特定定义的原因。  在iOS的AvailabilityMacros 中,对__attribute__ ((deprecated)) 进行了宏定义,DEPRECATED_MSG_ATTRIBUTE(s),其中s是可选参数表明编译是发出警告的内容,根据gcc标准其必须是字符串类型。

int main (void) __attribute__ ((weak, alias (“alt_main“)));嘛意思

__attribute__是gcc专有的,用来说明函数的熟性weak 和 alias 分别是两个属性。weak 使得 main 这个符号在目标文件中作为 weak symbol 而不是 global symbol。用 nm 命令查看编译 dummy.c 生成的目标文件可用看到 main 是一个 weak symbol,它前面的标记是 W。而 alias 则使main 是 alt_main 的一个别名,alt_main 和 main 必须在同一个编译单元中定义,否则会编译出错。

C程序必须从main()函数开始执行

这是在面试中被问到的一个问题,回答了是。这问题第一感觉答案就是否定的,一时也没想出来理由只能回答了是。当时太紧张了,其实回想一下汇编语言就该想到程序的入口地址是可以指定的,c语言编译器默认以main作为入口地址。

网上查阅后,发现了 __attribute__ 这个关键字,它可以设置函数属性,变量属性,类型属性。

1、前言

最近看到一份代码,看到一个函数前面用__attribute__((destructor))修饰,当时感觉有点怪怪的,搜了整个程序,也没发现哪个地方调用这个函数。于是从字面意思猜想,该函数会在程序结束后自动调用,与C++中的析构函数类似。第一次接触GNU下的attribute,总结一下。

2、__attribute__介绍

__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。__attribute__前后都有两个下划线,并且后面会紧跟一对原括弧,括弧里面是相应的__attribute__参数

__attribute__语法格式为:__attribute__ ( ( attribute-list ) )

若函数被设定为constructor属性,则该函数会在main()函数执行之前被自动的执行。类似的,若函数被设定为destructor属性,则该函数会在main()函数执行之后或者exit()被调用后被自动的执行。例如下面的程序:

#include 《stdio.h》 #include 《stdlib.h》 static int * g_count = NULL; __attribute__((constructor)) void load_file() {     printf("Constructor is called.\n");     g_count = (int *)malloc(sizeof(int));     if (g_count == NULL)     {     fprintf(stderr, "Failed to malloc memory.\n");     } } __attribute__((destructor)) void unload_file() {     printf("destructor is called.\n");     if (g_count)     free(g_count); } int main() {     return 0; }

程序执行结果如下:

看下面的例子:

// gcc 编译器#include《stdio.h》__attribute__((constructor)) void before_main(){    printf("%s\n",__FUNCTION__);}__attribute__((destructor)) void after_main(){    printf("%s\n",__FUNCTION__);}int main(){    printf("%s\n",__FUNCTION__);    return 0;}

输出结果为:before_main

main

after_main

可以看到上面的程序并不是从main函数开始执行的。constructor 设置在main前面执行,destructor 设置在main之后执行。

C语言 attribute的问题

对于你的问题不太明白。#define__init_call__attribute__((unused,__section__(".initcall.init")))参考GCC说明,意思是说所有以__init_call前缀定义的函数在链接过程中都放到名字为.initcall.init的段(section)里面。也就是说,如果一个函数冠以__init_call,那么它在编译链接的时候就会放到.initcall.init这个段里面。

如果你还想了解更多这方面的信息,记得收藏关注本站。

attribute函数(__attribute((constructor)) 在执行程序里失效,没有被调用,手动调用)

本文编辑:admin
Copyright © 2022 All Rights Reserved 威海上格软件有限公司 版权所有

鲁ICP备20007704号

Thanks for visiting my site.