0

Here is the code:

#include <stdio.h>

int *addition(int a, int b);

int result;
int *result_ptr;

int *addition(int a, int b)
{
    int c = a + b;
    int *d = &c;

    return d;
}

int main(void)
{
    result = *(addition(1,2));  
    result_ptr = addition(1,2);

    printf("result = %d\n", result); //outputline1
    printf("result_ptr = %d\n", *result_ptr); //outputline2

    return 0;
}

If it is complied and processed as the current code is written, result_ptr gives weird values. However, if you swap 2 output lines it doesn't. Why does it do that?

Oded
  • 489,969
  • 99
  • 883
  • 1,009
LarsChung
  • 703
  • 5
  • 10
  • 24
  • 5
    *Both* `result` and `result_ptr` are based on the address of a local-scope variable in `addition()` that is not in-scope when that address is used for evaluation. This is **undefined behavior**. – WhozCraig Sep 14 '13 at 11:06

1 Answers1

2

You are returning the address of the local variable c. This is undefined behavior. That is, your program is erroneous and this means that it has no obligation to show a predictable or sane behavior. Changing the position of the two printf gives you another erroneous program, which (again) is not required to behave correctly or coherently with the previous erroneous program.

EDIT (adding relevant citations from C99 draft standard N1256 - emphasis mine)

6.5.3.2 Address and indirection operators

[...]

Semantics

The unary * operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object. If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.87)

(footnote #87)

Thus, &*E is equivalent to E (even if E is a null pointer), and &(E1[E2]) to ((E1)+(E2)). It is always true that if E is a function designator or an lvalue that is a valid operand of the unary & operator, *&E is a function designator or an lvalue equal to E. If *P is an lvalue and T is the name of an object pointer type, *(T)P is an lvalue that has a type compatible with that to which T points.

Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, an address inappropriately aligned for the type of object pointed to, and the address of an object after the end of its lifetime.

The relevant sentence is the last one (emphasis mine): the c local variable has already ended its lifetime by the time when its address, which was returned by the addition function, is dereferenced in main.

Community
  • 1
  • 1