struct - Finding offset of a structure element in c - Stack Overflow
linux - How to design structure elements in c language by offset - Stack Overflow
How to write a long at an offset ?
offset meaning - C++ Forum
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/
This seems like a bad idea, but you can accomplish it by abusing a union and anonymous structure members:
#define SET_FIELD(Type, Name, Offset) \
struct { unsigned char Padding##Offset[Offset]; Type Name; }
#pragma pack(push, 1)
typedef union
{
SET_FIELD(unsigned int, field1, 15);
SET_FIELD(unsigned int, field2, 64);
SET_FIELD(unsigned int, field3, 93);
} ManualStructure;
#pragma pack(pop)
#include <stddef.h>
#include <stdio.h>
int main(void)
{
printf("field1 is at offset %zu.\n", offsetof(ManualStructure, field1));
printf("field2 is at offset %zu.\n", offsetof(ManualStructure, field2));
printf("field3 is at offset %zu.\n", offsetof(ManualStructure, field3));
}
The output of the above is:
field1 is at offset 15. field2 is at offset 64. field3 is at offset 93.
The fact that the array used for padding is named Padding##Offset will also alert you to erroneous uses of the same offset, since that will result in two members with the same name. However, it will not warn you of partial overlaps.
You can also do it with GCC and Clangโs attribute feature instead of a #pragma:
#define SET_FIELD(Type, Name, Offset) \
struct __attribute__((__packed__)) { unsigned char Padding##Offset[Offset]; Type Name; }
typedef union
{
SET_FIELD(unsigned int, field1, 15);
SET_FIELD(unsigned int, field2, 64);
SET_FIELD(unsigned int, field3, 93);
} ManualStructure;
A problem is that writing to any member of a union is allowed by the C standard to affect bytes that do not correspond to that member but that do correspond to others. For example, given ManualStructure x, the assignment x.field1 = 3; is allowed to alter the bytes of x.field3, since those bytes do not correspond to the bytes of the structure that contains x.field1. You might workaround this by including an additional member in each anonymous structure that pads its bytes out to the full length of the ManualStructure. Then, whenever you write to a field, you are writing to a member whose bytes occupy the entire union, so there are none that do not correspond to that member. However, to do this, you would have to know the total size of the structure in advance or at least be able to select some bound for it.
Premise: doing this is probably counter-productive, and may be solved in a different way, if you're willing to tell us why you need to specify members at specific offsets.
Actual answer: if I had your same problem, I'd solve it using an external scripting language in order to generate the struct definition before compiling the code.
For instance, you could type inside your .c or .h file a special comment like:
///DEFSTRUCT: mystruct (unsigned int, field1, 15) (unsigned int, field2, 25)
And then I'd write a quick script in JavaScript/Python/Perl/whatever that simply reads your .c or .h file, finds the lines that start with ///DEFSTRUCT: and then will replace them with the correct packed struct definition.
Doing this without an external scripting language would a great PITA, in my opinion. Plus, debugging a JavaScript/Python program is way easier than debugging the C preprocessor.
Hello there, i'm a bit confused on how to write a long at an arbitrary offset. Let's say you have a function with a void* parameter, an offset and a value that you want to assign. Would this simple solution be valid (in certain cases, in most cases, in all cases ) ?
void do_something_u64(void *ptr, usize_t offset, uint64_t value){
char *ptr8 = (char*)ptr;
uint64_t *ptr64 = (uint64_t*)&ptr8[offset];
*ptr64 = value;
}Edit : I need this meta instruction (for a project i'm working on). In some cases the address will be aligned, in others it will not. In some cases it will be possible to detect it to be alligned at compile time, in others it will not (even if it indeed always is). It really seems like it's a pretty basic instruction that fits well with the philosophy of C. But i'm very confused about how to handle it best for each possible case.
Edit 2 : i also need to be able to do the 32 bit version and 8 bit version in the same code base.
void write_u64(void *ptr, usize_t offset, uint64_t value); void write_u32(void *ptr, usize_t offset, uint32_t value); void write_u08(void *ptr, usize_t offset, uint8_t value);
bear soft sleep kiss thumb jellyfish library fearless oatmeal selective
This post was mass deleted and anonymized with Redact