Acceso al campo de estructura

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?

preguntado el 09 de septiembre de 13 a las 21:09

Yes. You are handing the address of someStruct.someField into func(). So func() dereferences that address and sets the value to SOME_OTHER_INT_VALUE. -

True. THere is no copying of someStruct.someField. -

someStruct.someField doesn't return anything, it is el campo. -

3 Respuestas

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)

contestado el 23 de mayo de 17 a las 13:05

Asumiendo que:

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

entonces sí.

Respondido el 09 de Septiembre de 13 a las 21:09

So, unlike function calls, struct member access doesn't return a copy? It's the assignment that performs the copy: int foo = someStruct.someField; foo now has a copy of someStruct.someField correct? - Kyle

No, it works because you are passing the ADDRESS of someStruct.someField a func. Si usted tiene int foo=7; luego func(&foo); también modificaría foo, no una copia de foo, because the value you are passing to func is the address of something (which is indeed a copy, so if you were to do val++; dentro func, foo would still stay in the same place) - esteras petersson

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.

En tu ejemplo

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.

Respondido el 09 de Septiembre de 13 a las 22:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.