0

Let's take the following two ways to create a 'Person' object with a name and age:

struct Person {
    char* Name;
    int   Age;
};
int using_struct() {
    struct Person amy;
    amy.Name = "Amy";
    amy.Age = 20;
    return 1;
};
int without_struct() {
    char* Name = "Amy";
    int  Age  = 20;
    return 1;
}

The compiler output looks very similar except for two things:

    # using_struct -- aligned on 16, Name at lowest address
    movq    $.LC0, -16(%rbp)
    movl    $20, -8(%rbp)

    # manually -- aligned by type size
    movq    $.LC0, -8(%rbp)
    movl    $20, -12(%rbp)
  1. The struct aligns differently (uses 16 bytes instead of 12 in the above example).
  2. The struct allocates variables with increasing storage whereas the other/stack way aligns it descendingly.

When all is said and done, they seems very very similar in how the compiler treats them. Is the struct then mainly a "programmer convenience" to use, or is it fundamentally different than defining the items manually each time?

samuelbrody1249
  • 4,379
  • 1
  • 15
  • 58
  • Yes, I would say that `struct` is for the programmer's benefit. You could say the same thing about arrays or enums or many other C constructs. Sure, you could try to do everything with individual variables but that would quickly become impractical if not impossible. Not sure what point you are really trying to get at. – kaylum Nov 01 '20 at 02:53
  • @kaylum sure, I was actually just surprised at how similar they were by the compiler. I thought that using a `struct` was going to produce wildly different compiler output but it doesn't. – samuelbrody1249 Nov 01 '20 at 02:56
  • 1
    Your example is not really the point of having `struct`. Think instead about how you would handle an array of 5000 of the structs. For one thing, with an array of structs, the members are kept contiguous in memory, instead of being far apart - that's better for caching. Also think about the benefits of passing one struct pointer to a function, instead of 3 or 30 distinct arguments. – Nate Eldredge Nov 01 '20 at 02:57
  • @NateEldredge right yea I see the benefits I was just curious about how the compiler handles them. I currently have a program (not in C though) that has over a hundred variables for an object and so not really possible to pass along all the variables, just the object itself. – samuelbrody1249 Nov 01 '20 at 03:00
  • *The struct allocates variables with increasing storage whereas the other/stack way aligns it descendingly.* - The stack layout of loose local variables is a coincidence, not guaranteed or required by anything. – Peter Cordes Nov 01 '20 at 04:23
  • @PeterCordes I see -- why a coincidence though? If they're in consecutive statements and both put to memory wouldn't the first one have a higher memory address than the second on a stack frame? – samuelbrody1249 Nov 01 '20 at 04:30
  • 1
    @samuelbrody1249: There's no reason for a compiler to lay out locals in source order. Grouping ones of the same size together will avoid wasting space on padding for alignment, for example. (If you had multiple 4-byte and 8-byte objects). Depending on compiler internals, they might end up laid out in reverse order, or even an order that happened to match a hash table it used to keep track of locals that had been declared. In optimized code, many locals don't need to get spilled to the stack at all, which might or might not affect ordering of ones that do get stack space. – Peter Cordes Nov 01 '20 at 04:32
  • @PeterCordes I see. Thanks for the detailed explanation. – samuelbrody1249 Nov 01 '20 at 04:35
  • Also, GCC likes to put arrays at the top of stack frames, closest to the stack cookie when `-fstack-protector-strong` is used. This makes overwriting other locals less likely to be possible with buffer overflow attacks. (And overwriting the return address would require overwriting the stack cookie.) A smart compiler could even group locals together to allow optimizations like loading or copying a pair of them with one wide load (qword integer, or 8 or 16-byte XMM.) GCC unfortunately doesn't; [Why are compilers not generating more efficient assembly?](https://stackoverflow.com/q/63355199) – Peter Cordes Nov 01 '20 at 04:38
  • [Order of variable declaration in asm x86?](https://stackoverflow.com/q/35166434) shows an example of `-fstack-protector`. – Peter Cordes Nov 01 '20 at 04:38

0 Answers0