Are there any guarantees regarding the structure order of C?

I used structures heavily and I saw interesting things, especially *valueinstead value->first_value, where value is a pointer to a struct, first_valueis the very first member *valuesafe?

Also note that sizes are not guaranteed due to alignment, what is the alginment value based on architecture / register size?

We align the data / code for faster execution, can we tell the compiler not to do this? so maybe we can guarantee certain things about structures, like their size?

When doing pointer arithmetic on structure elements to find the offset of the member, I suppose you do -if the endian is small +for the large endian, or does it just depend on the compiler?

what does malloc (0) really emit?

The following code is intended for educational / search purposes, it is not intended to ensure product quality.

#include <stdlib.h>
#include <stdio.h>

int main()
{
    printf("sizeof(struct {}) == %lu;\n", sizeof(struct {}));
    printf("sizeof(struct {int a}) == %lu;\n", sizeof(struct {int a;}));
    printf("sizeof(struct {int a; double b;}) == %lu;\n", sizeof(struct {int a; double b;}));
    printf("sizeof(struct {char c; double a; double b;}) == %lu;\n", sizeof(struct {char c; double a; double b;}));

    printf("malloc(0)) returns %p\n", malloc(0));
    printf("malloc(sizeof(struct {})) returns %p\n", malloc(sizeof(struct {})));

    struct {int a; double b;} *test = malloc(sizeof(struct {int a; double b;}));
    test->a = 10;
    test->b = 12.2;
    printf("test->a == %i, *test == %i \n", test->a, *(int *)test);
    printf("test->b == %f, offset of b is %i, *(test - offset_of_b) == %f\n",
        test->b, (int)((void *)test - (void *)&test->b),
        *(double *)((void *)test - ((void *)test - (void *)&test->b))); // find the offset of b, add it to the base,$

    free(test);
    return 0;
}

call gcc test.cfollowed by ./a.out I get the following:

sizeof(struct {}) == 0;
sizeof(struct {int a}) == 4;
sizeof(struct {int a; double b;}) == 16;
sizeof(struct {char c; double a; double b;}) == 24;
malloc(0)) returns 0x100100080
malloc(sizeof(struct {})) returns 0x100100090
test->a == 10, *test == 10 
test->b == 12.200000, offset of b is -8, *(test - offset_of_b) == 12.200000

Update is my car:

gcc --version

i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

uname -a

Darwin MacBookPro 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun  7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386
+1
source share
5 answers

I used structures heavily, and I saw interesting things, especially *valueinstead value->first_value, where valueis a pointer to a struct, first_valueis this the very first element, is it *valuesafe?

, *value ; , value . *value->first_value, *value *value->first_value.


Counter-:

struct something { struct something *first_value; ... };
struct something data = { ... };
struct something *value = &data;
value->first_value = value;

*value *value->first_value. ( ). *value *value->first_value .


, - , ?

" " C, , . (#pragma pack ) , ( ).

/ ; , ? , , ?

struct. , , #pragma pack .

, (, , ). , , , .

, , , , endian, endian, ?

, struct. , offsetof() <stddef.h>, ( , ). , . , ; ( ) .

C , , ; , - .. . . . , , , . , (N × ) , (, malloc()) .

+2

6.2.5/20:

- (, , ), , , .

:

* value- > first_value, value - struct, first_value - , value safe?

. 6.7.2.1/15:

15 , - , , . , , ( -, , ) . , . 1

, .

C, malloc( 0 ) . ( , , C ++.)

[1] .

+7

malloc(0) , free() . malloc(0), . , NULL, free() . malloc(0), non-null, free() .

+3

, , , .

So *value value->first ( )

struct St {
  long first;
} *value;

, ,

, -.

memebers , .

, malloc , , ( - )

+1

, . :

struct foo{
  int i;
  char c;
}

struct bar{
  int i;
  int j;
}

struct baz{
  int i;
  char c;
  int j;
}

sizeof(foo) = 8 bytes (32 bit arch)
sizeof(bar) = 8 bytes
sizeof(baz) = 12 bytes

, :

1- The string must be a multiple of its first element (why foo - 8 is not 5 bytes)

2- The struct element must begin with the most multiple. (In baz int j cannot start with 6, so bytes 6, 7 and 8 are lost in an empty place

0
source

All Articles