FW: noreturn atribute and its optimization

Avi Kivity avi@scylladb.com
Sun Nov 1 17:06:00 GMT 2015



On 11/01/2015 01:11 PM, boris smidt wrote:
> Dear,
>
> I have been playing around with the noreturn atribute and  created the following program (i know this is not thr right way to write C):
>
> #include <stdio.h>
> static void loop()__attribute__((noreturn,nothrow));
> //int main()__attribute__((noreturn,nothrow));
> static void loop(int a)
> {
>      int b= a+1;
>      printf("Hello World %u!\n",b);
>      loop(b);
> }
>
> int main()
> {
>      int b= 1;
>      printf("Hello World %u!\n",b);
>      loop(b);
> }
>
>
>
> I would have expected this program to run forever. But when i looked at the generated assembly code with -O3 it calls the function loop and allocates stack in the loop function and thus crashes.
> But i wonder why  this function doesn't clear/reset the stack, since it is a "no return function" and thus can never return to older stack references.

The noreturn attribute is an indication to the caller that the callee 
does not return, and thus it can optimize the caller accordingly, and 
avoid warnings about missing return values in the caller.

It does not direct the compiler to optimize the callee, and even if it 
did, with optimizations disabled, it wouldn't.

>
> When i compiled the program it with -O3, without the atributes, it generates the expected result. i.e. a jump to the function label and no allocating on the stack.
>
>
> Here is the generated assembly:
>
>
> with atrributes
>       .file    "main.c"
>      .section .rdata,"dr"
> .LC0:
>      .ascii "Hello World %u!\12\0"
>      .text
>      .p2align 4,,15
>      .def    loop;    .scl    3;    .type    32;    .endef
>      .seh_proc    loop
> loop:
>      pushq    %rbx
>      .seh_pushreg    %rbx
>      subq    $32, %rsp
>      .seh_stackalloc    32
>      .seh_endprologue
>      leal    1(%rcx), %ebx
>      leaq    .LC0(%rip), %rcx
>      movl    %ebx, %edx
>      call    printf
>      movl    %ebx, %ecx
>      call    loop
>      nop
>      .seh_endproc
>      .def    __main;    .scl    2;    .type    32;    .endef
>      .section    .text.startup,"x"
>      .p2align 4,,15
>      .globl    main
>      .def    main;    .scl    2;    .type    32;    .endef
>      .seh_proc    main
> main:
>      subq    $40, %rsp
>      .seh_stackalloc    40
>      .seh_endprologue
>      call    __main
>      leaq    .LC0(%rip), %rcx
>      movl    $1, %edx
>      call    printf
>      movl    $1, %ecx
>      call    loop
>      nop
>      .seh_endproc
>      .def    printf;    .scl    2;    .type    32;    .endef
>
>
> without attributs
>      .file    "main.c"
>      .def    __main;    .scl    2;    .type    32;    .endef
>      .section .rdata,"dr"
> .LC0:
>      .ascii "Hello World %u!\12\0"
>      .section    .text.startup,"x"
>      .p2align 4,,15
>      .globl    main
>      .def    main;    .scl    2;    .type    32;    .endef
>      .seh_proc    main
> main:
>      pushq    %rbx
>      .seh_pushreg    %rbx
>      subq    $32, %rsp
>      .seh_stackalloc    32
>      .seh_endprologue
>      movl    $1, %ebx
>      call    __main
>      leaq    .LC0(%rip), %rcx
>      movl    $1, %edx
>      call    printf
>      .p2align 4,,10
> .L2:
>      addl    $1, %ebx
>      leaq    .LC0(%rip), %rcx
>      movl    %ebx, %edx
>      call    printf
>      jmp    .L2
>      .seh_endproc
>
>      .def    printf;    .scl    2;    .type    32;    .endef
>
>
>
>
>
>          



More information about the Gcc-help mailing list