-1

How the function fun is returning the pointer to the node created even though I haven't used any return statement. Consequently, the value in the nodes get successfully printed. How?

#include <stdio.h>
#include"stdlib.h"

struct node
{
  int data;
  struct node *next;
};

main ()
{
  struct node *nl=fun();
  printf("%d",nl->data);
}

fun ()
{
    struct node *p= (struct node*)malloc(sizeof (struct node));
    scanf("%d", &(p->data));
    p->next=NULL;
}
agenius5
  • 21
  • 1
  • 5
  • Show a sample run. This looks like complete nonsense. – Mad Physicist Jun 09 '18 at 17:24
  • Show your compiler output too. I refuse to believe it's silent if it compiles at all. – Mad Physicist Jun 09 '18 at 17:26
  • 1
    If you don't return a value you generally get whatever nonsense was on the stack or in a register that is used as the return value. It's undefined behavior which means many things can happen, including appearing to work normally. But, use a different compiler or change that function a little and it will do something completely different. – Retired Ninja Jun 09 '18 at 17:32
  • This is very legacy C. Please don't. Find up-to-date learning material and learn how functions should be declared and defined. – hyde Jun 09 '18 at 18:19
  • I am using codeblocks on linux and the compilers which comes with it, which I guess is gcc. I am merely a beginner so I was just experimenting with things and the codes runs. I give input, let's say, 12 then 12 get printed on the next line. I don't from where to post a photo as I am new on SO too. – agenius5 Jun 10 '18 at 17:51

2 Answers2

1

Older versions of C allowed functions to not specify return type, and the return type was automatically int.

And if a function is declared to return a value (explicitly, or as in your case implicitly) then it must return a value or you will have undefined behavior.

Also note that in older versions of C, the compiler would automatically declare functions it had never seen before when called. Both this and the implicit return type are very prone to errors and was therefore removed with the C99 standard.


Lastly a note about using int for pointers: Often in computer history, pointers and int are not equal. For example these days, on a 64-bit system then pointers are usually 64 bits, while int is 32 bits. You can't fit a 64 bit pointer in a 32 bit int, no matter how hard you try. This is one reason you should never cast the result of malloc.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    In older versions of C, all functions returned something. On X86 the function return was the ax register, so anything in the ax register was interpreted as the function return. – Paul Ogilvie Jun 09 '18 at 17:44
  • 1
    It is not automatically undefined behavior for a non-void function not to return a value. It is only undefined if the value of the function call is used, per C 2011 [N1570] 6.9.1 12. – Eric Postpischil Jun 09 '18 at 21:22
1

For this statement

struct node *nl=fun(); /* here nl expecting something from fun() but 
                      you didn't return anything, in your case default int is  
                      returning, which can cause serious problem as 
                      nl expects valid address */

your compiler could have warned you like

error: return type defaults to ‘int’ [-Werror=return-type]

If you compiled your program with -Wall -Wstrict-prototypes -Werror option, otherwise behavior is undefined.

correct version could be

struct node* fun (void) {
        struct node *p= malloc(sizeof (struct node)); /* avoid casting result of malloc() */
        scanf("%d", &(p->data));
        p->next=NULL;
        return p; /* return the dynamic memory so that you can do 
                     nl->data in main() as you are doing */
}

Also just main () { /*code */ } is not a good practise, use int main(void) { /* code */ } as specified in C standard here https://port70.net/~nsz/c/c11/n1570.html#5.1.2.2.1p2.

Achal
  • 11,821
  • 2
  • 15
  • 37