简体   繁体   English

gcc 的 used 属性的用例是什么?

[英]What's the usecase of gcc's used attribute?

#include <stdio.h>

// xyz will be emitted with -flto (or if it is static) even when
// the function is unused

__attribute__((__used__))
void xyz() {
  printf("Hello World!\n");
}

int main() {
  return 0;
}

What do I need this for?我需要这个做什么?

Is there any way I could still reach xyz somehow besides directly calling the function, like some dlsym() like magic?除了直接调用函数之外,我还有什么办法可以达到xyz ,比如像魔术一样的dlsym()吗?

Attribute used is helpful in situation when you want to force compiler to emit symbol, when normally it may be omitted. 当您希望强制编译器发出符号时, used属性很有用,通常可以省略它。 As GCC's documentation says (emphasis mine): 正如GCC的文件所述 (强调我的):

This attribute, attached to a function, means that code must be emitted for the function even if it appears that the function is not referenced. 附加到函数的此属性意味着即使看起来函数未被引用,也必须为函数发出代码。 This is useful, for example, when the function is referenced only in inline assembly . 例如,仅在内联汇编中引用该函数时 ,这很有用。

For instance, if you have code as follows: 例如,如果您有如下代码:

#include <iostream>

static int foo(int a, int b)
{
    return a + b;
}

int main()
{
   int result = 0;

   // some inline assembly that calls foo and updates result

   std::cout << result << std::endl;
}

you might notice, that no symbol foo is present with -O flag (optimization level -O1 ): 您可能会注意到, -O标志(优化级别-O1 )不存在符号foo

g++ -O -pedantic -Wall check.cpp -c
check.cpp:3: warning: ‘int foo(int, int)’ defined but not used
nm check.o | c++filt | grep foo

As a result you cannot reference foo within this (imaginary) inline assembly. 因此,您无法在此(虚构的)内联汇编中引用foo

By adding: 通过增加:

__attribute__((__used__))

it turns into: 它变成了:

g++ -O -pedantic -Wall check.cpp -c
nm check.o | c++filt | grep foo
00000000 t foo(int, int)

thus now foo can be referenced within it. 因此现在foo可以在其中引用。

You may also have spotted that gcc 's warning is now gone, as you have tell you compiler that you are sure that foo is actually used "behind the scene". 您可能还发现gcc的警告现在已经消失,因为您已经告诉编译器您确定foo实际上是在“幕后”使用的。

A particular usecase is for interrupt service routines in a static library. 特定用例用于静态库中的中断服务例程。 For example, a timer overflow interrupt: 例如,定时器溢出中断:

void __attribute__((interrupt(TIMERA_VECTOR),used)) timera_isr(void)

This timera_isr is never called by any function in the user code, but it might form an essential part of a library. 此timera_isr永远不会被用户代码中的任何函数调用,但它可能构成库的基本部分。 To ensure it is linked and there isn't a interrupt vector pointing to an empty section the keyword ensures the linker doesn't optimise it out. 为了确保链接并且没有指向空部分的中断向量,关键字确保链接器不会优化它。

If you declare a global variable or function that is unused, gcc will optimized it out (with warning), but if you declared the global variable or the function with '__attribute__((used))' , gcc will include it in object file (and linked executable).如果您声明了一个未使用的全局变量或函数,gcc 将对其进行优化(带有警告),但如果您使用'__attribute__((used))'声明了全局变量或函数,gcc 会将其包含在目标文件中(和链接的可执行文件)。

https://gcc.gnu.org/legacy-ml/gcc-help/2013-09/msg00108.htmlhttps://gcc.gnu.org/legacy-ml/gcc-help/2013-09/msg00108.html

Another use case is to generate proper coverage information for header files.另一个用例是为头文件生成适当的覆盖信息。 Functions declared in header files are usually removed by the compiler when unreferenced.在头文件中声明的函数通常在未引用时被编译器删除。 Therefore, you will get 100% coverage in your coverage reports even if you forgot to call some functions that are located in the header file.因此,即使您忘记调用位于头文件中的某些函数,您的覆盖率报告也将获得 100% 的覆盖率。 To prevent this, you may mark your function with __attribute__((used)) in your coverage builds.为了防止这种情况,您可以在覆盖构建中__attribute__((used))标记您的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM