Kyle
Kyle

Reputation: 1019

Struct field access

Is the return value of someStruct.someField a copy of the field? If I get a pointer to that value, will the pointer point to the value in the struct or a copied value on the stack?

e.g. Is the following guaranteed(it appears to work in a simple test) to work?

struct SomeStruct {
    int someField;
    SomeStruct() : someField(0) {}
}

void func(int* val) {
    *val = 42;
}

SomeStruct someStruct;
func(&(someStruct.someField));

// Is it guaranteed that someStruct.someField == 42?

Upvotes: 1

Views: 664

Answers (3)

Rodrigo
Rodrigo

Reputation: 231

When you access a structure's field in that way, you are not calling a method, so that doesn't return anything (and in consequence it can't be a copy).

What you are really doing is to access directly your structure's field, then SomeStruct.someField is the current structure's field, you can change it and/or reference it.

In your example

SomeStruct someStruct;
func(&(someStruct.someField));

, what you are doing is giving a pointer right to your structure's field, so you can do whatever you want with it.

Upvotes: 0

Leeor
Leeor

Reputation: 19706

Seems legit, see here -

How to pass a struct member as a pointer in a function

If you want to make sure for yourself, you can compile and look at the assembly code, you'll see that the compiler passes the direct address to tha given element, without copying anything "out" of it.

Take for e.g. this code:

typedef struct {
    int a;
    int b;
    int c;
} T;

void set(int* c) {
    *c = 0;
}

int main()
{
    T t;
    set(&(t.b));
    set(&(t.c));

    return 0;
}

built (with gcc 4.2.2, -O2), and disassembled with objdump, the main function gives:

0000000000400500 <main>:
  400500:       53                      push   %rbx
  400501:       48 83 ec 10             sub    $0x10,%rsp     //"allocates" t on the stack
  400505:       48 8d 7c 24 04          lea    0x4(%rsp),%rdi //creates a direct pointer the t.b
  40050a:       e8 e1 ff ff ff          callq  4004f0 <set>
  40050f:       48 8d 7c 24 08          lea    0x8(%rsp),%rdi //creates a direct pointer the t.c
  400514:       e8 d7 ff ff ff          callq  4004f0 <set>
  400519:       8b 44 24 04             mov    0x4(%rsp),%eax
  40051d:       03 44 24 08             add    0x8(%rsp),%eax
  400521:       48 83 c4 10             add    $0x10,%rsp
  400525:       5b                      pop    %rbx
  400526:       c3                      retq

00000000004004f0 <set>:
  4004f0:       c7 07 00 00 00 00       movl   $0x0,(%rdi)
  4004f6:       c3                      retq

So the modifying function would write directly into the original struct defined, unless of course at some point along the way you do create a copy of it (which is a common mistake, for example by creating T t2 = t)

Upvotes: 2

Mats Petersson
Mats Petersson

Reputation: 129364

Assuming that:

  1. SOME_OTHER_INT_VALUE actually fits in an int
  2. Compiler doesn't have serious bugs.

then yes.

Upvotes: 1

Related Questions