0

Can you please explain, why this program works:

#include<stdio.h>

int main()
{
    struct first{
        char *name;
        int a;
    };

    struct second{
        struct first *second;
        int z;
    };

    struct first *FIRST, C;
    FIRST = &C;
    
    struct second *SECOND, b;
    SECOND = &b;
    
    
    SECOND->second->a = 9;

    printf("%d", SECOND->second->a);


    return 0;    
}

while this doesn't:

#include<stdio.h>

int main()
{
    struct first{
        char *name;
        int a;
    };

    struct second{
        struct first *second;
        int z;
    };

    //struct first *FIRST, C;
    //FIRST = &C;
    
    struct second *SECOND, b;
    SECOND = &b;
    
    
    SECOND->second->a = 9;

    printf("%d", SECOND->second->a);


    return 0;    
}

In short, can you please tell me why do I need to add those two commented-out lines in the code above? I am a beginner in this field. So, it would be very kind of you if you help me.

Thanks in advance!

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 1
    Also your first code does not work. `SECOND->second` points nowhere, so `SECOND->second->a = 9;` is undefined behavior. You probably forgot `SECOND->second = FIRST;`. Always read the compiler output: https://godbolt.org/z/zrT87r3W7 – mch Nov 12 '21 at 09:18
  • Neither example is correct, you aren't initializing the pointers to point at something valid. See the linked duplicate and also [What is undefined behavior and how does it work?](https://software.codidact.com/posts/277486) – Lundin Nov 12 '21 at 09:34

2 Answers2

3

The both programs have undefined behavior.

Within the object b having the type struct second

struct second *SECOND, b;

the data member second having a pointer type is not initialized and has an indeterminate value. So dereferencing this pointer in this statement

SECOND->second->a = 9;

results in undefined behavior.

The first program could be correct if the object b would be initialized as for example

struct second *SECOND, b = { FIRST };
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

Short answer: because your code is illegal, so that compiler fails to understand what you mean.

In both code snippt, SECOND->second points to nowhere(you did not assign value to it) and by SECOND->second->a you are dereferencing SECOND->second. It's called Undefined Behaviour(UB). Explanation is below.

ISO Standard of C tries hard to leave room for compilers to optimize your code. Their effort includes providing some strong assumption to compiler(that something should not happen).

ISO Standard does not require compiler to perform consistently for same kind of UB. It pretend this volation of rule never happens, so it can happily adjust your code to run faster. It does not necessarily fail to print 9, but you can not rely on it, as it may fails and even cause problem that is hard to diagnosis.(Actually both of your code fragments fails to print 9 in my enviroment.)

If you turn on (exactly speaking do not turn off) warning option of your compiler, it will warn you for this. Just don't write your code this way.

breaksuika
  • 34
  • 4
  • Thanks, but, can you please correct this code? It would help me as I am new to this field. And, also, that will be easier for me to understand. – Tashif Iqbal Nov 12 '21 at 09:38
  • Re “In your case, second::second is of type struct first * but you assigned a struct second * value to it”: Which line of code does that? Nowhere in the code shown is a member named `second` assigned any value. – Eric Postpischil Nov 12 '21 at 12:30
  • My fault. I did not inspect code thoroughly. In your code SECOND->second is not assigned any value, and deref such a pointer is illegal. – breaksuika Nov 15 '21 at 01:52