struct - Finding offset of a structure element in c - Stack Overflow
How does the C offsetof macro work? - Stack Overflow
c - What is the correct way to offset a pointer? - Stack Overflow
C/C++ Structure offset - Stack Overflow
Videos
Use offsetof() to find the offset from the start of z or from the start of x.
offsetof() - offset of a structure member
SYNOPSIS
#include <stddef.h>
size_t offsetof(type, member);
offsetof() returns the offset of the field member from the
start of the structure type.
EXAMPLE
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
struct s {
int i;
char c;
double d;
char a[];
};
/* Output is compiler dependent */
printf("offsets: i=%ld; c=%ld; d=%ld a=%ld\n",
(long) offsetof(struct s, i),
(long) offsetof(struct s, c),
(long) offsetof(struct s, d),
(long) offsetof(struct s, a));
printf("sizeof(struct s)=%ld\n", (long) sizeof(struct s));
exit(EXIT_SUCCESS);
}
You will get the following output on a Linux, if you compile with GCC:
offsets: i=0; c=4; d=8 a=16
sizeof(struct s)=16
It's been 3 years since the question has been asked, I'm adding my answer for the sake of completeness.
The hacky way of getting the offset of a struct member goes like this
printf("%p\n", (void*)(&((struct s *)NULL)->i));
It doesn't look pretty, I can't think of anything in pure C (which can get you the offset of the member, without knowing anything else about the structure. I believe the offsetof macro is defined in this fashion.
For reference, this technique is used in the linux kernel, check out the container_of macro :
http://lxr.free-electrons.com/source/scripts/kconfig/list.h#L18
A more elaborate explanation can be found in this article:
http://radek.io/2012/11/10/magical-container_of-macro/
R.. is correct in his answer to the second part of your question: this code is not advised when using a modern C compiler.
But to answer the first part of your question, what this is actually doing is:
(
(int)( // 4.
&( ( // 3.
(a*)(0) // 1.
)->b ) // 2.
)
)
Working from the inside out, this is ...
- Casting the value zero to the struct pointer type
a* - Getting the struct field b of this (illegally placed) struct object
- Getting the address of this
bfield - Casting the address to an
int
Conceptually this is placing a struct object at memory address zero and then finding out at what the address of a particular field is. This could allow you to figure out the offsets in memory of each field in a struct so you could write your own serializers and deserializers to convert structs to and from byte arrays.
Of course if you would actually dereference a zero pointer your program would crash, but actually everything happens in the compiler and no actual zero pointer is dereferenced at runtime.
In most of the original systems that C ran on the size of an int was 32 bits and was the same as a pointer, so this actually worked.
It has no advantages and should not be used, since it invokes undefined behavior (and uses the wrong type - int instead of size_t).
The C standard defines an offsetof macro in stddef.h which actually works, for cases where you need the offset of an element in a structure, such as:
#include <stddef.h>
struct foo {
int a;
int b;
char *c;
};
struct struct_desc {
const char *name;
int type;
size_t off;
};
static const struct struct_desc foo_desc[] = {
{ "a", INT, offsetof(struct foo, a) },
{ "b", INT, offsetof(struct foo, b) },
{ "c", CHARPTR, offsetof(struct foo, c) },
};
which would let you programmatically fill the fields of a struct foo by name, e.g. when reading a JSON file.
That would do, but just make it:
writeSECTOR( destAddress, &BufferData[i * 512]);
(It sounds like writeSECTOR really should take an unsigned char* though)
Pointer arithmetic is fairly simple to understand. If you have a pointer to the first element of an array, then p + 1 points to the second element and so on regardless of size of each element. So, even if you had an array of ints, or an arbitrary structure MyData, it would hold true.
MyData data[100];
MyData *p1 = data; // same as &data[0]
MyData *p2 = p1 + 1; // same as &data[1]
MyData *p3 = p2 + 1; // same as &data[2]
MyData *p4 = p2 - 1; // same as &data[0] again
If your array is unsigned char, then you just add however many bytes offset you wish to go into the array, e.g.
unsigned char data[16384];
unsigned char *offset = data + 512; // same as &data[512]
*offset = 5; // same as data[512] = 5;
Alternatively, if the notation is confusing, you can always refer to it as it is shown in comments above, e.g. &data[512]
How about the standard offsetof() macro (in stddef.h)?
Edit: for people who might not have the offsetof() macro available for some reason, you can get the effect using something like:
#define OFFSETOF(type, field) ((unsigned long) &(((type *) 0)->field))
Right, use the offsetof macro, which (at least with GNU CC) is available to both C and C++ code:
offsetof(struct mstct, myfield2)
bear soft sleep kiss thumb jellyfish library fearless oatmeal selective
This post was mass deleted and anonymized with Redact