1

The below program is having two structures. I don't understand how I can pass value from one structure variable to another structure variable while using pointers

#include <stdio.h>

typedef struct {
 int c;
 char d;
}bob;

typedef struct {
int c;
char d;
}anna;

//expecting 'bob' type variable
void fun(bob *var2)
{

printf("var2->c=%d\n",var2->c);
printf("var2->d=%c\n",var2->d);

}

int main()

{
anna var1;
var1.c=2;
var1.d='c';
fun(&var1);//passing 'anna' type pointer
return 0;
}

...but if I change the program to pass values using normal variables, it gives compilation error.

#include <stdio.h>

typedef struct {
 int c;
 char d;
}bob;

typedef struct {
int c;
char d;
}anna;

//expecting a variable of type 'bob'
void fun(bob var2)
{

printf("var2.c=%d\n",var2.c);
printf("var2.d=%c\n",var2.d);

}

int main()

{
anna var1;
var1.c=2;
var1.d='c';
fun(var1);//passing a variable of type 'anna'
return 0;
}

What is the logic behind this?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261

2 Answers2

1

First of all, the first version, does warn you. with proper compiler options enabled, you'll see

source_file.c: In function ‘main’:
source_file.c:30:5: warning: passing argument 1 of ‘fun’ from incompatible pointer type

fun(&var1);//passing 'anna' type pointer
 ^

source_file.c:16:6: note: expected ‘struct bob *’ but argument is of type ‘struct anna *’

void fun(bob *var2)

That said, in the first version of the code

//expecting 'bob' type variable

is wrong!! Its ought to be (follow emphasis)

//expecting a pointer to 'bob' type variable

As per C rules, a pointer to a type can be converted to another type, but the result is not always defined. So, the first version of the code compiler (with warnings) and runs.

OTOH, in the second case, anna and bob are different types, so the inter-change is not possible while passing the argument and receiving the parameter. To the compiler, they are different types and compiler behaves accordingly.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

Answer for beginner/intermediately experienced:

Any two structure types in C with different type names are not compatible types. No matter if they happen to have the same member variables. Similarly, pointers to different structure types are not compatible. So your types "bob" and "anna" are not compatible, and using them like you attempt is formally not safe nor well-defined.

Simply refrain from doing things like this, you will end up writing subtle bugs.


Answer for veterans:

Despite the type compatibility rules mentioned above, C (but not C++) allows some tricks to let you use one memory region in several different ways, no matter the type of the variables stored there. This is known as "type punning". Most often type punning is done through union, for example:

typedef struct
{
  bob b;
  anna a;
} bobanna;

If you would use a pointer to a type like the one above, you are actually allowed to assume that either of the two types can be used, but only because in this case, all the involved struct/union members contain (recursively) the very same types. For example, code like this is fine:

void fun (bobanna *var)
{
  bob* b = var.b;
  b.c = something;
}

bobanna ba = {.anna.c = 1 };
fun(&ba);

Please note that type punning is an advanced topic. It is very easy to do things like this in the wrong way - I would not recommend to even consider the above trick if you don't already know about pointer aliasing and the strict aliasing rule.

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396