Разница между размещением gcc __attribute__ - PullRequest
0 голосов
/ 03 декабря 2018

Играя с gcc __attribute__ для функций, я заметил, что существует разница в генерации кода в зависимости от того, где я размещаю атрибут.В приведенных ниже примерах я хочу, чтобы компилятор не оптимизировал мой вызов для использования ().

Компилятор: x86-64 gcc (транк)

Опции: -O3 -Wall

void  __attribute__((noinline, optimize("O0"))) use() {} 
int main () 
{
    use();
}
use:
        push    rbp
        mov     rbp, rsp
        nop
        pop     rbp
        ret
main:
        xor     eax, eax
        call    use
        xor     eax, eax
        ret

Однако, если я изменю расположениеатрибут, генерируется другой код.

void   use() {} __attribute__((noinline, optimize("O0")))
int main () 
{
    use();
}
main:
        push    rbp
        mov     rbp, rsp
        mov     eax, 0
        pop     rbp
        ret
use:
        ret

Если я не помещаю какие-либо атрибуты, я получаю это:

void   use() {} 
int main () 
{
    use();
}
use:
        ret
main:
        xor     eax, eax
        ret

Теперь атрибуты, которые я вижу, атрибуты используются в gcc_Common-Function-Attributes все присутствуют в объявлениях функций, а не в определениях.Я не уверен, стоит ли мне использовать их только в объявлениях (поскольку использование их в определении, кажется, работает в одном примере выше). Мой вопрос: каковы правила размещения __attribute__ и почему вышеприведенное ведет себя так, как оно?Я проверил gcc_Attribute-Syntax , но, боюсь, я его не очень хорошо понял.

1 Ответ

0 голосов
/ 03 декабря 2018

__attribute__ является частью спецификации функции, которая следует за ней.Ваша вторая версия на самом деле:

__attribute__((noinline, optimize("O0"))) int main() {
    ...
}

Вы устанавливаете атрибуты функции main(), а не функции use().

Помните, что у новинок нет специальныхэто означает, что при синтаксическом анализе C-кода размещение атрибута в той же строке, что и объявление use(), фактически не делает его частью этого.

...