views:

269

answers:

5

Here is a particular scenario that I have been unclear about (in terms of scope) for a long time.

consider the code

#include <stdio.h>


typedef struct _t_t{
 int x;
 int y;
} t_t;

typedef struct _s_t{
 int a;
 int b;
 t_t t;
}s_t;

void test(s_t & s){
 t_t x = {502, 100};
 s.t = x;
}


int main(){
 s_t s; 
 test(s);

 printf("value is %d, %d\n", s.t.x, s.t.y);
 return 0;
}

the output is

value is 502, 100

What is a bit confusing to me is the following. The declaration

t_t x

is declared in the scope of the function test. So from what I have read about C programming, it should be garbage out of this scope. Yet it returns a correct result. Is it because the "=" on the line s.t = x; copies the values of x into s.t?

edit---

after some experimentation

#include <stdio.h>


typedef struct _t_t{
 int x;
 int y;
} t_t;

typedef struct _s_t{
 int a;
 int b;
 t_t t;
}s_t;

void test(s_t & s){
 t_t x = {502, 100};
 t_t * pt = &(s.t);
 pt = &x;
}


int main(){
 s_t s; 
 test(s);

 printf("value is %d, %d\n", s.t.x, s.t.y);
 return 0;
}

actually outputs

value is 134513915, 7446516

as expected.

+7  A: 

Is it because the "=" on the line s.t = x; copies the values of x into s.t?

Yes.

By the way, this is C++. You've passed the "s" local to main as a reference to the function, which modifies it. Because it's a reference, and not a copy, it affects the caller's "s".

wrang-wrang
A: 

You're right, the line

s.t = x;

will copy the values over.

Soo Wei Tan
+6  A: 
   t_t x = {502, 100};
   s.t = x;

In your first test, you're instructing the compiler to copy the value of x into s.t - this works as expected. The local variable x goes out of scope, but is never referenced outside of the function - the data it initially contained is copied into the t member of main()'s local variable s. It would be effectively the same if you instead wrote:

t_t x = {502, 100};
s.t.x = x.x;
s.t.y = x.y;

In your second test, you assign a pointer to another pointer, both of which are declared as local variables. This does nothing useful - the value in s.t remains uninitialized. I've annotated the code to help you follow it:

t_t x = {502, 100}; // local variable x initialized with 502, 100
t_t * pt = &(s.t); // local variable pt initialized with ADDRESS OF s.t
pt = &x; // local variable pt re-assigned to hold address of local variable x

// local variables go out of scope, output parameter s remains unmodified
Vagabond
+1  A: 

Read This : Default copy-constructors and assignment operators

By not providing an assignment operator, the struct _s_t will do a shallow-copy of all its members when it is assigned. Because you are storing everything in _t_t by value, all of the data is copied by value.

The problem you are describing is when _t_t holds a pointer to the data.

in the case:

typedef struct _s_t{
        int a;
        int b;
        t_t* t;
}s_t;

void test(s_t & s){
        t_t x = {502, 100};
        s.t = &x;
}

This would cause a problem, as t_t would be destructed at the end of test() at which point that pointer would be invalid.

ETA: Because you added more to the question...

void test(s_t & s){
     t_t x = {502, 100};
     t_t * pt = &(s.t);
     pt = &x;
}

You've created a different problem here. What has happened there is you have created a pointer to the address of s.t, which is fine. However you have then reassigned that pointer to point to x (this assignment, did nothing to s.t, you are just changing what the pointer pt points to) The reason the output is 'as expected' is because you are just reading the uninitialised state of the struct.

Salgar
A: 

An asignment copies the value from one variable into another variable. So although the original local x is gone, you've got a copy in s.

It would be quite different when you've just assigned a pointer to x:

typedef struct _s_t{
        int a;
        int b;
        t_t* t;
}s_t;

void test(s_t & s){
        t_t x = {502, 100};
        s.t = &x;
}

Then you would have a problem: you only have the address of x but x is gone. So you've effectively have a reference to an invalid memory location. The behaviour of this program would be undefined then.

codymanix