Friday, May 31, 2019

Calling function with no return statement, and using its returned value in C

The C language or at least Gcc has weird behavior. Test.c
       
#include 
int function1()
{
}

int main() 
{
   int rval;
   rval = function1();
   if (rval)
      printf("%d\n", rval);
  return 0;
}
       
 
When compiling with the command line gcc Test.c -o Test it does not show any error at all So the executable Test will be generated and when executing the application, the variable rval will contain undetermined value. Taking a look at the assembly code generated by using gcc Test.c -s
       
...................
function1:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        nop
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc

............
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $16, %rsp
        movl    $0, %eax
        call    function1
        movl    %eax, -4(%rbp)
        cmpl    $0, -4(%rbp)
        je      .L3
        movl    -4(%rbp), %eax
        movl    %eax, %esi
        leaq    .LC0(%rip), %rdi
        movl    $0, %eax
        call    printf@PLT
       
 
We can see that after the instruction call function1, it executes movl %eax, -4(%rbp), where it moves the value of $eax to -4(%rbp), which points to address of the variable rval in the stack. And after that it uses it in a if statement that can be evaluated as true or false depending on the value of eax, and as we can see the code for function1 does not change eax value, because there is no return instruction for that. ....................... Changing the code a little bit, just adding the return 3 instrunction in function1, we can see that now it moves a determined value to eax register.
       

int function1()
{
   return 3;
}
       
 
       

function1:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    $3, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
       
 
To force error in compilation for this case use -Werror=return-type in gcc arguments

No comments:

Blog Archive