I want the size of a C struct to be multiple of 16 bytes (16B/32B/48B/..).
It does not matter which size it gets to; it only needs to be multiple of 16 bytes.
How could I enforce the compiler to do that?
For Microsoft Visual C++:
#pragma pack(push, 16)
struct _some_struct
{
...
}
#pragma pack(pop)
For GCC:
struct _some_struct { ... } __attribute__ ((aligned (16)));
Example:
#include <stdio.h>
struct test_t {
int x;
int y;
} __attribute__((aligned(16)));
int main()
{
printf("%lu\n", sizeof(struct test_t));
return 0;
}
compiled with gcc -o main main.c will output 16. The same goes for other compilers.
The size of a C struct will depend on the members of the struct, their types and how many of them there are. There is really no standard way to force the compiler to make structs to be a multiple of some size. Some compilers provide a pragma that will allow you to set the alignment boundary however that is really a different thing. And there may be some that would have such a setting or provide such a pragma.
However if you insist on this one method would be to do memory allocation of the struct and to force the memory allocation to round up to the next 16 byte size.
So if you had a struct like this.
struct _simpleStruct {
int iValueA;
int iValueB;
};
Then you could do something like the following.
{
struct _simpleStruct *pStruct = 0;
pStruct = malloc ((sizeof(*pStruct)/16 + 1)*16);
// use the pStruct for whatever
free(pStruct);
}
What this would do is to push the size up to the next 16 byte size so far as you were concerned. However what the memory allocator does may or may not be to give you a block that is actually that size. The block of memory may actually be larger than your request.
If you are going to do something special with this, for instance lets say that you are going to write this struct to a file and you want to know the block size then you would have to do the same calculation used in the malloc() rather than using the sizeof() operator to calculate the size of the struct.
So the next thing would be to write your own sizeof() operator using a macro such as.
#define SIZEOF16(x) ((sizeof(x)/16 + 1) * 16)
As far as I know there is no dependable method for pulling the size of an allocated block from a pointer. Normally a pointer will have a memory allocation block that is used by the memory heap management functions that will contain various memory management information such as the allocated block size which may actually be larger than the requested amount of memory. However the format for this block and where it is located relative to the actual memory address provided will depend on the C compiler's run time.
This depends entirely on the compiler and other tools since alignment is not specified that deeply in the ISO C standard (it specifies that alignment may happen at the compilers behest but does not go into detail as to how to enforce it).
You'll need to look into the implementation-specific stuff for your compiler toolchain. It may provide a #pragma pack (or align or some other thing) that you can add to your structure defininition.
It may also provide this as a language extension. For example, gcc allows you to add attributes to a definition, one of which controls alignment:
struct mystruct { int val[7]; } __attribute__ ((aligned (16)));
You could perhaps do a double struct, wrapping your actual struct in a second one that can add padding:
struct payload {
int a; /*Your actual fields. */
float b;
char c;
double d;
};
struct payload_padded {
struct payload p;
char padding[16 * ((sizeof (struct payload) + 15) / 16)];
};
Then you can work with the padded struct:
struct payload_padded a;
a.p.d = 43.3;
Of course, you can make use of the fact that the first member of a structure starts 0 bytes from where the structure starts, and treat a pointer to struct payload_padded as if it's a pointer to a struct payload (because it is):
float d_plus_2(const struct payload *p)
{
return p->d + 2;
}
/* ... */
struct payload_padded b;
const double dp2 = d_plus_2((struct payload *) &b);
Related
I was implementing a structure in which I needed (at runtime) to have an optional field.
So I thought about this:
//...
#include <stdlib.h>
struct test {
int x; // Must be
int y; // Optional (Must be the last field..(?))
};
int main(int argc, char **argv) {
// With the optional field
struct test *a = malloc(sizeof(*a));
a->x = 11;
a->y = 55;
// Without the optional field
struct test *b = malloc(sizeof(*b) - sizeof(int));
b->x = 22;
// ...
free(a);
free(b);
return 0;
}
Could this code do what I ask?
Possibly adding a bit field to check if there is the optional field or not.
Also, if the proposed solution works, if this were implemented for a list of multiple items (> 100000), would it be better to do it to save memory?
Could this code do what I ask?
Well, it could, but you cannot rely on that. Do not do this; it is not a way to write correct programs.
When you write b->x = 22;, the compiler is entitled to behave as if there were a whole struct test at b. You may be thinking, “I am just putting 22 in the bytes for the member x,” but the compiler may use a “store eight bytes” instruction:
Consider some architecture where memory is organized into eight-byte groups. The bus can only read and write whole eight-byte chunks.
Since there is no way to write four bytes in hardware, writing four bytes to memory requires reading eight bytes, manipulating them in processor registers to insert the desired values in four of the bytes, and writing eight bytes back to memory.
The compiler wants to optimize b->x = 22;, and it knows y has not been set yet, so it is allowed to have any value. So, instead of using an inefficient write-four-byte sequence, the compiler generates an eight-byte store that puts 22 in b->x and 0 in b->y.
Then this fails because the compiler has just written 0 to memory that might be in use for something else because it is not part of the space you allocated for b.
“If you lie to the compiler, it will get its revenge.” — Henry Spencer
What you're attempting doesn't conform to the C standard because you're attempting to use an object of type struct test that doesn't have enough memory allocated for it, even though you're only accessing the fields for which memory was allocated. It might work but you can't rely on that.
What you can do is make use of a flexible array member:
struct test {
int x;
int y[];
};
In a struct like this, sizeof(struct test) doesn't include the last member. You can use such a struct by allocating space for the struct plus as many array elements of the last member that you want. For example:
struct test *b = malloc(sizeof(*b) + sizeof(int));
b->x = 1;
b->y[0] = 2;
You'll need to use array indexing to access the last member, but this is a way to do what you want in a standard-conforming manner.
Then in the case you don't want the last member, you do this:
struct test *b = malloc(sizeof(*b));
b->x = 1;
I think your proposed solution is dangerous. Use two different structs:
struct test_x {
int x;
};
struct test_xy {
int x;
int y;
};
Either have two arrays or store a void * to either along with a discriminator (tagged pointer for instance). The other option is use a pointer for the optional element but sizeof(int *) is the same as sizeof(int) at least on my box, so that only makes things larger.
Consider a column layout if all the y members are optional, or you can sort the data so all the xy elements comes first:
struct test_column {
int *x;
int *y;
};
struct test_column t = {
.x = malloc(100000 * sizeof(int)),
.y = 0
It doesn't help you in case but unions are the standard way to two structs share memory so size of each element is
max(sizeof(test_xy), sizeof(test_x)) instead of sizeof(test_xy) + sizeof(test_x).
Finally, consider compression especially if you use the test_column format.
I have the following header file:
struct StackList_s;
typedef struct StackList_s StackList_t;
// From here I add in the method signatures
And the following source file:
struct StackList_s
{
integer_t count;
struct StackListNode_s *top; // Here begins the linked list
// Some other members that store information about the stack
integer_t version_id;
};
// From here I define StackListNode_s and implement the StackList_s functions
// Note that the user will never manipulate directly a StackListNode_s
// There are functions that will handle the free() of each node correctly
I hide the struct definition in the source file so that anyone using this stack can't modify directly its members, since changing them requires some input treatment or checking for certain invalid states.
Currently, to get a new stack you have to use the following:
// malloc(sizeof(StackList_t)) and set members to default
StackList_t *stack = stl_new(/* Some info parameters */);
But I can only do this allocating a StackList_t in the heap. What I want to do is to have the StackList_t allocated on the stack and then its nodes can be allocated in the heap allong with their data and pointers to other nodes. This way I can give the user a choice, if either the struct is being used locally or if he will pass it around functions as an allocated resource.
StackList_t stack;
stl_init(&stack, /* Info parameters */); // No malloc, only setting members to 0
But of course I can't do this because the definition of struct StackList_s is in the source file. So here are my questions:
Is it possible to, at the same time, not allow access to members of a struct and allocate that same struct in the stack?
Is there any way to tell the compiler the size of my struct?
You can do that with VLAs or alloca in Linux:
Library header:
struct StackList_s;
typedef struct StackList_s StackList_t;
extern const size_t StackList_size;
// If you're using VLAs
extern const size_t StackList_align;
StackList_t* stl_init_inline(char stack_source[], ...);
Library source:
#include "header.h"
struct StackList_s {
// ...
};
const size_t StackList_size = sizeof(StackList_t);
// If you're using VLAs
#include <stdalign.h>
#include <stdint.h>
const size_t StackList_align = alignof(StackList_t);
StackList_t* stl_init_inline(char stack_source[], ...) {
// align the address to the nearest multiple of StackList_align
uintptr_t address = (uintptr_t) ((void*) stack_source);
if (address % StackList_align != 0) {
address += StackList_align - address % StackList_align;
}
StackList_t* stack = (StackList_t*) ((void*) address);
stl_init(stack, ...);
return stack;
}
Main source
#include <header.h>
StackList_t* stack = alloca(Stacklist_size);
stl_init(stack, ...);
char stack_source[StackList_size + StackList_align - 1]; // Not compile time.
StackList_t* stack = stl_init_inline(stack_source, ...);
This would allocate it on the stack, and you won't need to free it, but it's slower and more verbose than just StackList_t stack_source;. (And alloca is Linux only)
For the second question, you need the full definition of a struct to get it's size. Common pitfalls include the fact that sizeof(struct { int a; }) == sizeof(struct { int a; }) can be false. It probably won't be though, so you can do #define StackList_size sizeof(struct { integer_t count; struct StackListNode_s *top; integer_t version_id; }) but that also leads to a lot of code duplication.
I personally would just put the struct definition in the header file, and just declare "don't mess with the members or my methods won't work" in a comment somewhere (Maybe making the names start with _ to give a hint that they are private)
You could do something similar to Artyer's answer without using VLA's by using a #define instead
Header:
#define STACKLISTSIZE 32
typedef uint8_t stl_storage[STACKLISTSIZE];
typedef struct stacklist_s stacklist_t;
stacklist_t* stl_create_from_stack(stl_storage b); //user provides memory
stacklist_t* stl_allocate(void); //library allocates memory, user must free.
Source:
int myfunction()
{
stl_storage x;
stacklist_t* sp = stl_create_from_stack(x);
//do something with sp.
}
Make sure you have a compile-time assert that sizeof(stack_s) == STACKSTRUCTSIZE in the implementation file.
Some implementations guarantee that calls between compilation units will be processed in a fashion consistent with the platform's Application Binary Interface (ABI), without regard for what a called function is going to do with storage whose address it receives, or what a caller will have done with storage whose address it supplies, or will do with such storage once the function returns. On such implementations, given something like:
// In header
typedef union FOO_PUBLIC_UNION {
uint64_t dat[4]; // Allocate space
double dummy_align1; // Force alignment
void *dummy_align2; // Force alignment
} FOO;
void act_on_foo(FOO_PUBLIC_UNION*);
// In code
FOO x = {0};
act_on_foo(&x);
in one compilation unit, and something like:
struct FOO_PRIVATE {
int this; float that; double whatever;
};
typedef union FOO_PUBLIC_UNION { uint64_t dat[4]; struct FOO_PRIVATE priv; } FOOPP;
void act_on_foo(FOO *p)
{
FOOPP *pp = (FOOPP*)p;
pp->priv.whatever = 1234.567;
}
provided that the size of FOO and FOOPP match, the behavior of calling an external function from the first compilation unit would be defined as allocating sizeof(FOO) bytes, zeroing them, and passing their address to act_on_foo, whose behavior would then be defined as acting upon the bytes to which it receives an address, without regard for how they got their values or what the caller would do with them later.
Unfortunately, even though almost every implementation should be capable of producing behavior consistent with calling a function it knows nothing about, there is no standard way of indicating to a compiler that a particular function call should be viewed as "opaque". Implementations intended for purposes where that would be useful could and typically did support such semantics with "ordinary" function calls whether or not the Standard required that, and such semantics would offer little value on implementations intended only for purposes where they wouldn't be useful. Unfortunately, this has led to a Catch 22: there's no reason for the Standard to mandate things implementations would be free to do, with or without a mandate, in cases where they're useful, but some compiler writers treat the Standard's lack of a mandate as an encouragement to deny support.
I have a structure where the first element is tested and dependent on its value the rest of the structure will or will not be read. In the cases where the first element's value dictates that the rest of the structure will not be read, do I have to allocate enough memory for the entire structure or just the first element?
struct element
{
int x;
int y;
};
int foo(struct element* e)
{
if(e->x > 3)
return e->y;
return e->x;
}
in main:
int i = 0;
int z = foo((struct element*)&i);
I assume that if only allocating for the first element is valid, then I will have to be wary of anything that may attempt to copy the structure. i.e. passing the struct to a function.
don't force your information into structs where it's not needed: don't use the struct as the parameter of your function.
either pass the member of your struct to the function or use inheritance:
typedef struct {
int foo;
} BaseA;
typedef struct {
int bar;
} BaseB;
typedef struct {
BaseA a;
BaseB b;
} Derived;
void foo(BaseB* info) { ... }
...
Derived d;
foo(&d.b);
BaseB b;
foo(&b);
if you're just curious (and seriously don't use this): you may.
typedef struct {
int foo, goo, hoo, joo;
} A;
typedef struct {
int unused, goo;
} B;
int foo(A* a) { return a->goo; }
...
B b;
int goo = foo((A*)&b);
In general you'll have to allocate a block of memory at least as many bytes as are required to fully read the accessed member with the largest offset in your structure. In addition when writing to this block you have to make sure to use the same member offsets as in the original structure.
The point being, a structure is only a block of memory with different areas assigned different interpretations (int, char, other structs etc...) and accessing a member of a struct (after reordering and alignment) boils down to simply reading from or writing to a bit of memory.
I do not think the code as given is legitimate. To understand why, consider:
struct CHAR_AND_INT { unsigned char c; int i; }
CHAR_AND_INT *p;
A compiler would be entitled to assume that p->c will be word-aligned and have whatever padding would be necessary for p->i to also be word-aligned. On some processors, writing a byte may be slower than writing a word. For example, a byte-store instruction may require the processor to read a word from memory, update one byte within it, and write the whole thing back, while a word-store instruction could simply store the new data without having to read anything first. A compiler that knew that p->c would be word-aligned and padded could implement p->c = 12; by using a word store to write the value 12. Such behavior wouldn't yield desired results, however, if the byte following p->c wasn't padding but instead held useful data.
While I would not expect a compiler to impose "special" alignment or padding requirements on any part of the structure shown in the original question (beyond those which apply to int) I don't think anything in the standard would forbid a compiler from doing so.
You need to only check that the structure itself is allocated; not the members (in that case at least)
int foo(struct element* e)
{
if ( e != 0) // check that the e pointer is valid
{
if(e->x != 0) // here you only check to see if x is different than zero (values, not pointers)
return e->y;
}
return 0;
}
In you edited change, I think this is poor coding
int i = 0;
int z = foo((struct element*)&i);
In that case, i will be allocation on the stack, so its address is valid; and will be valid in foo; but since you cast it into something different, the members will be garbage (at best)
Why do you want to cast an int into a structure?
What is your intent?
I am using a library that has a function that takes an array of structs. That struct and function has the following layout:
struct TwoInt32s
{
int32_t a;
int32_t b;
};
void write(struct TwoInt32s *buffer, int len);
My initial tests suggest that an array of such structs has the same memory layout as an array of int32_t so I can do something like this:
int32_t *buffer = malloc(2 * len * sizeof(int32_t));
/* fill in the buffer */
write((struct TwoInt32s*)buffer, len);
However I'm wondering if this is universally true or not. Using an array of int32_t greatly simplifies my code.
EDIT: I forgot the sizeof
From what I read, C guarantees a few things about struct padding:
members will NOT be reordered
padding will only be added between members with different alignments or at the end of the struct
a pointer to a struct points to the same memory location as a pointer to its first member
each member is aligned in a manner appropriate for its type
there may be unnamed holes in the struct as necessary to achieve alignment
From this I can extrapolate that a and b have no padding between them. However it's possible that the struct will have padding at the end. I doubt this since it's word-aligned on both 32 and 64 bit systems. Does anyone have additional information on this?
The implementation is free to pad structs - there may be unused bytes in between a and b. It is guaranteed that the first member isn't offset from the beginning of the struct though.
Typically you manage such layout with a compiler-specific pragma, e.g:
#pragma pack(push)
#pragma pack(1)
struct TwoInt32s
{
int32_t a;
int32_t b;
};
#pragma pack(pop)
malloc allocates bytes. Why did you choose "2*len" ?
You could simply use "sizeof":
int32_t *buffer = malloc(len * sizeof(TwoInt32s));
/* fill in the buffer */
write((struct TwoInt32s*)buffer, len);
and as Erik mentioned, it would be a good practice to pack the struct.
It's safest to not cast, but convert -- i.e., create a new array and fill it with the values found in the struct, then kill the struct.
You could allocate structures but treat their members as a sort of virtual array:
struct TwoInt32s *buffer = malloc(len * sizeof *buffer);
#define BUFFER(i) (*((i)%2 ? &buffer[(i)/2].b : &buffer[(i)/2].a))
/* fill in the buffer, e.g. */
for (int i = 0; i < len * 2; i++)
BUFFER(i) = i;
Unfortunately, neither GCC nor Clang currently "get" this code.
I declared a Normal Structure In C:
typedef struct arr_struct{
int* original;
int size;
int first[size/2];
int second[size-(size/2)];
};
when compile it gives me:
test.c:11: error: ‘size’ undeclared here (not in a function)
any explanation?
You can't define arrays based on a variable size. The size has to be known at compile time. You'll need to make first and second pointers and dynamically allocate them once size is known.
You're getting the error message because you're trying to use the size member of the struct illegally. For one thing, the struct type definition isn't complete until the closing }, so until then the compiler doesn't know that there's a size member within the struct. For another, you cannot refer to a struct member without a struct instance; when you used the expression size the declarators for first and second, the compiler was looking for a variable named size outside of the struct definition.
It is possible to use a VLA within a struct type, but that's really not the approach you want to take here if you're doing what I think you're doing. Better to make first and second pointers to int and allocate them as necessary (as demonstrated by a couple of the answers above).
int val;
scanf("%d",&val);
int a[val];
The above code actually compiles and runs in my gcc compiler.
The reason for not working inside a struct could be due to the lining up of elements inside a struct whose size can't be determined at compile time. I am not fully sure about it though.
An implementation and usage for what miked said could be (without error checking):
typedef struct
{
int size;
int* first;
int* second;
} arr_struct;
// Prepare an arr_struct for use.
arr_struct foo;
foo.size = 1337;
foo.first = malloc(sizeof(int)*foo.size);
foo.second = malloc(sizeof(int)*(foo.size-foo.size/2));
Do remember to free(foo.first) and free(foo.second) when you're done, though!
The size you provide for an array needs to be a constant expression. You have a couple of choices. One would be to include a couple of pointers, and allocate the space dynamically:
typedef struct {
int* original;
int size;
int *first;
int *second;
} arr_struct;
Another possibility would be to use only one array, and create a pointer to the proper point in it:
typedef struct {
int* original;
int size;
int *second;
int first[];
} arr_struct;
This uses a flexible array member, which is new with C99 -- if you're using an out of date C compiler (e.g., MS VC++) it might not be supported directly1. In any case, this still requires dynamic allocation, but lets you do one large allocation for all the data instead of three separate allocations (one for the struct, and one each for first and second).
arr_struct *my_struct = malloc(sizeof(*my_struct) + size * sizeof(int));
my_struct->second = my_struct->first + size/2;
As an aside, note the syntax for typedef -- as it was, your typedef wasn't defining a name at all.
1The workaround is trivial though -- just define first with a size of 1 and subtract 1 from size in your allocation:
arr_struct *my_struct = malloc(sizeof(*my_struct) + (size-1) * sizeof(int));
In theory, this isn't required to work, but in fact it's just fine with all real compilers, at least AFAIK.