J.Ens
J.Ens

Reputation: 11

x86 variable alignment in memory without struct using C

I use C on a x86 based CPU. There are lot of articles that explain the alignment of variables in the memory by using structs and #pragma pack directives. That's all nice as long you are willing to use structs.

I am looking for a way to ensure the alignment of variables in the memory (order and size) WITHOUT using a struct.

Ist there any way to do this?

In the form of

#pragma (push)
**#pragma "anyalignment directive"**
int a;
byte b;
long l;
#pragma (pop)

Upvotes: 1

Views: 2489

Answers (3)

Lundin
Lundin

Reputation: 214300

There is no standard way to enforce allocation order in memory without using struct. You would have to resort to non-standard syntax to allocate the variables at fixed addresses.

As for alignment, you can force a wider alignment than the default one, by using the standard C _Alignas keyword. Example:

#include <stdio.h>

// force 16 byte alignment:
int _Alignas(16) x;
int _Alignas(16) y;
int _Alignas(16) z;

int main (void)
{
  printf("%p\n", (void*)&x);
  printf("%p\n", (void*)&y);
  printf("%p\n", (void*)&z);
  return 0;
}

Output for me on gcc/mingw in Windows is

0000000000407970
0000000000407990
0000000000407980

The alignment requirement of 16 bytes is satisfied, but as we can see this does not affect the allocation order.

Upvotes: 1

Blagovest Buyukliev
Blagovest Buyukliev

Reputation: 43538

With GCC attributes, you could ensure the alignment of each variable like this:

int a __attribute__((aligned(16)));
byte b __attribute__((aligned(2)));
long l __attribute__((aligned(32)));

But then, why would you need that? The compiler is free to reorder the declarations in a way that it sees fit (unlike struct members, there is no requirement that the variables should reside adjacently, or even be in memory).

Also, crossing the boundaries of these variables with pointers will result in undefined behaviour. You cannot assume that b will come right after a and that there will be a gap of a definite size between them.

Upvotes: 1

John Zwinck
John Zwinck

Reputation: 249394

If you're using GCC or Clang, it's like this:

int x __attribute__((aligned(16)));

https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html

In MSVC:

__declspec(align(16)) int x;

https://msdn.microsoft.com/en-us/library/83ythb65.aspx

Upvotes: 2

Related Questions