-6

Not able to understand the code. The correction option is d but i m not understanding how it comes out to be d.

#include <stdio.h>
int *m();
void main()
{
    int k = m();
    printf("%d",k);
}
int *m()
{
    int a[2]={5,8};
    return a;
}

options are:

a) 5
b) 8
c) nothing
d) varies

The compiler is showing following warnings:

1)warning: return makes integer from pointer without a cast
 return a;
2)warning: function returns address of local variable [-Wreturn-local-addr]

and I am not able to interprete both.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • 2
    There are no options. This question is very confusing. – Eli Sadoff Nov 08 '16 at 18:18
  • You cannot validly return a local array from a function to be of use. Even if you found a way, you cannot print that array with a single statement. Did you take any notice of the compiler warnings? – Weather Vane Nov 08 '16 at 18:21
  • Your question looks very low-effort - all you have is a pasted snippet of code. It sounds like there's a list of multiple choice answers to choose from, but you haven't provided that context. Also, provide code annotations to express what you think is happening in the code, and people can understand where your thoughts are and help. It'd also be helpful to format your code. – Kache Nov 08 '16 at 18:21
  • but they are saying D is correct. – Abhishek kumar Nov 08 '16 at 18:22
  • How come there's no "fails to compile" option? – Sergey Kalinichenko Nov 08 '16 at 18:22
  • 1
    Who taught you `void main()`? – Weather Vane Nov 08 '16 at 18:23
  • 3
    E) undefined behaviour. – Weather Vane Nov 08 '16 at 18:25
  • I don't even see what are these options for... – Eugene Sh. Nov 08 '16 at 18:25
  • 1
    Whoever set this question doesn't understand it well enough themselves. That's why none of the options include the correct answer. – P.P Nov 08 '16 at 18:28
  • i copied the code as it is from the website. – Abhishek kumar Nov 08 '16 at 18:29
  • i dont remember the website.i have a screenshot of the question but i am not able to post that image along with my code. – Abhishek kumar Nov 08 '16 at 18:36
  • See the dup: [returning a local variable from function in C](http://stackoverflow.com/questions/4824342/returning-a-local-variable-from-function-in-c). – P.P Nov 08 '16 at 18:36
  • @WeatherVane Actually... Why is it UB? The returned pointer is not dereferenced. Pointers can be casted to `int`.. – Eugene Sh. Nov 08 '16 at 18:40
  • @EugeneSh. I am sure you already know that from your comment *"Varies" is a stupid description of UB*. – Weather Vane Nov 08 '16 at 18:43
  • @WeatherVane I have removed it as now I am rethinking it :) – Eugene Sh. Nov 08 '16 at 18:43
  • 1
    @Abhishekkumar: are you sure the assignment wasn't supposed to be `int k = *m();`? And beware of random websites teaching C - most of the ones I've seen range from not-very-good to downright awful. – John Bode Nov 08 '16 at 18:47
  • I've pretty much convinced myself it is not a UB.. – Eugene Sh. Nov 08 '16 at 18:51
  • The code presented does not go with the warnings presented. Specifically, "*return makes integer from pointer without a cast*" is not a problem with the code presented. That would be an expected warning if function `m()` were declared to return `int` (for example), but not if, as is the case, it returns `int *`. There is an *assignment* that makes an integer from a pointer without a cast, but that's not the compiler's complaint, nor is it the line the compiler flags. – John Bollinger Nov 08 '16 at 18:58

4 Answers4

4

It's no surprise you have trouble understanding that code, because it is very poorly written.

The main problem is that the a array in the m() function ceases to exist when m returns, so any pointer to that array is no longer valid1, and attempting to read or write anything through an invalid pointer leads to undefined behavior.

"Undefined behavior" simply means that the code is erroneous, but the compiler isn't required to handle it in any specific way. Your program may crash outright, it may be put into a bad state that doesn't manifest until later, it may corrupt data, or it may appear to run without any issues.

So yes, the result may vary, but that's understating the case by a lot. The right answer is "E) The behavior is undefined".

But there are other problems in the code. m() returns a pointer to int, but the program assigns the result to a plain int, hence the first warning. Whoever wrote that code either doesn't understand types, or assumes that pointer values and int values are interchangeable (not necessarily a valid assumption).

Either that, or the original code is actually

int k = *m();

And, finally, main() returns int, not void, as in:

int main( void )  // or int main( int argc, char **argv ) if your program takes
                  // command line arguments.


  1. Obviously, the memory location that a occupied still exists, but after m() exits, that memory may be overwritten or used by something else.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • 1
    But the code *doesn't* attempt to dereference the returned pointer. It converts it to `int`, as you observed, and then prints that resulting `int`. The conversion technically requires a cast (and no warning about that is presented), but that doesn't cause the pointer to be dereferenced. – John Bollinger Nov 08 '16 at 19:11
1

Thanks for making updates to your question, I think I understand what's going on, now. My C is a bit rusty, but here goes:

  1. The method m returns an int* (pointer/address to int)

  2. When m is called, it creates a as a local array on the stack. Then, it tries to return the address for a.

  3. When m is completed and returns control back to main, the memory on allocated by m on the stack goes out of scope. a is among the items on that stack that has gone out of scope.

  4. Because the data at the address a is out of scope, it's considered "undefined behavior" to access/dereference it, which is what main (almost) does with the printf call. This is what 2)warning: function returns address of local variable [-Wreturn-local-addr] is warning you of.

The answer, "varies", would've been more accurate as "undefined behavior".

A separate issue highlighted by the error:

1)warning: return makes integer from pointer without a cast

Is that m() returns a pointer to an int, but it's being assigned to int k.

Kache
  • 15,647
  • 12
  • 51
  • 79
  • Not quite and not quite. It's ok to return a pointer to a local variable. The problem is not returning such a pointer, but rather *dereferencing* such a pointer after the function returns, which in fact the OP's code does not do. It is because of that (potential) problem, though, that the compiler warns about returning such a pointer. – John Bollinger Nov 08 '16 at 19:06
  • The other warning is a different matter, as it does not correspond to the code presented. You're right that the assignment could plausibly elicit a warning about pointer conversion, but *that's not the warning the OP reported*. – John Bollinger Nov 08 '16 at 19:08
1

The first warning (MSVC compiler)

int differs in levels of indirection from int *

is because you are trying to supply a pointer for int k in main, which is not a pointer.

The second warning

returning address of local variable or temporary: a

is because a function's local variable goes out of life after the function returns.

I would suggest you use malloc in your function to obtain memory for the array, and return that to a pointer variable in main. Having done that, you can print the first element. But I won't post the code for that, since you "copied the code as it is from the website".

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
0

The reason that the behavior "varies" (D) is because m() is returning a, which is a memory address. Each time you run your program, that address could change because your OS can load the program anywhere in memory that it wants.

Now if your program were doing what I think you actually want it to - to print the contents at the memory address returned by m() - that would be:

int *k = m();
printf("%d\n", *k);

But this would still result in behavior "varies" though, for the local variable issue described by the other answers.

Your compiler warning: 2)warning: function returns address of local variable [-Wreturn-local-addr] is occurring because m() is returning a, which is a local variable. Look up "local variables" on the googles for more information. This is useful: Difference between static, auto, global and local variable in the context of c and c++

Your compiler warning: 1)warning: return makes integer from pointer without a cast is because you're storing the return value of m(), which is of type int* into variable k, which is of type int. You need to make these the same type in order to get rid of the compiler warning. Look up "C pointers" on the googles for more information. This tutorial seems reasonable: http://www.programiz.com/c-programming/c-pointers

Community
  • 1
  • 1
lyst
  • 371
  • 1
  • 10