使用GCC“人工”函数属性的用例

时间:2013-11-21 00:47:12

标签: c gcc attributes

我刚刚阅读了GCC函数属性artificial,但没有完全得到描述。你能给我一些有用的例子吗?

3 个答案:

答案 0 :(得分:12)

另一个答案没错,但也许我可以更好地解释一下。

想象一下foo.c中的这个函数,行号:

10: static inline int foo(struct q *x)
11: {
12:     return bar(x + 1);
13: }

这是从另一个函数调用两次:

20: void baz(void)
21: {
22:     x = foo(qa);
23:     x = foo(qb);
24: }

不幸的是,bar()崩溃了。这是回溯:
#0 0x00000000004b1a2a in bar (x=0x8) at foo.c:5 #1 0x0000000000416ee0 in baz () at foo.c:12 #2 0x0000000000413fab in main () at foo.c:30

由于foo是内联的,因此它不属于回溯,但等待foo.c:12位于foo,而低于它main。没有什么可以告诉我们baz中的哪一行导致了崩溃。

如果我们将foo标记为人为的,我们反而得到这个回溯:
#0 0x00000000004b1a2a in bar (x=0x8) at foo.c:5 #1 0x0000000000416ee0 in baz () at foo.c:22 #2 0x0000000000413fab in main () at foo.c:30

它不再指向foo。相反,它向我们显示了从foo调用foo.c:22的位置。非常容易说出qa是有问题的变量。

答案 1 :(得分:4)

人工

来自gcc文档,

  

此属性对于小型内联包装器非常有用,如果可能,应在调试期间将其作为一个单元出现。根据调试信息格式,它或者意味着将函数标记为人工,或者使用内联体内所有指令的调用者位置。

Inline is as fast as a Macro中,extern inline函数的末尾有一个特殊注释。我们的想法是,如果您有一个带有extern inline的标头,则可以使用 artificial 属性,调试信息将使用inline所使用的位置。即,extern inline被调用,内联

与说明中一样,人工仅用于内联,它控制调试器处理此代码的方式。它对生成的代码或其他任何内容都没有影响。

答案 2 :(得分:1)

GCC开发人员Ian Lance Taylor在__gnu_inline__ and __artificial__表示:

  

我承认人工属性的文档不是很好。在一个   函数,它基本上意味着如果函数是内联的,那么   调试器不会单步执行内联指令。

  

你能给我一些有用的例子吗?

我至少可以提供一个额外的一个:带有内联汇编单行代码的步进代码。很多时候,你需要下一个C语句,而不是下一个汇编语句。