Is this a portable way to make a stack buffer eight-byte aligned?

struct {
  uint64_t a; char z[120];
} b;

...

struct buffer_with_alignment_requirement* c = (struct buffer_w*)&b;
c->start_using_it;

Without the first member a, we might crash when accessing fields in the buffer. Is it portable and correct to simply add a member like this to force aligment for the whole struct to be strict enough?

This is not a question about pointer aliasing, simply about whether the address of b on the stack is always eight-byte aligned.

Answers


It depends on what you mean by aligned. If you want (uintptr_t)&b % 8 == 0, there is no portable way to obtain this, as the conversion from pointer to integer is implementation-defined and need not be any sane, natural mapping.

If all you want is for the buffer to be sufficiently aligned for access with type uint64_t, your solution works perfectly well. But why don't you just use (possibly an array of) type struct buffer_with_alignment_requirement, rather than the ugly union hackery? In other words, just give the buffer the right type you intend to access it as to begin with. You can pass a pointer to any type to read, fread, revc, etc. and other functions that you might be using to write into the buffer, and even if you'll be passing it to a function that expects a buffer pointer of type char * or unsigned char *, you can just cast when passing it; this cast is perfectly well-defined and valid.


The exact-width integer types, if they exist (7.20.1.1p3), do not have any particular alignment requirements other than that they should be at least as aligned as char and no more aligned than max_align_t (6.2.8p2-4). There is not even any requirement that alignment should follow integer conversion rank, except of course that corresponding signed and unsigned types should have the same alignment (6.2.5p6).

If you want a particular alignment, use an alignment specifier:

#include <stdalign.h>
struct alignas(8) {
  char z[120];
} b;

However, presumably given your description of accessing fields, what you actually want is for the buffer to be aligned to the most aligned type that could exist within the buffer. To do this C11 provides max_align_t; in older compilers you can emulate max_align_t using a union of the standard types:

typedef union {
  char c;
  short s;
  int i;
  long l;
  long long ll;  // if available
  float f;
  double d;
  long double ld;  // if available
  void *p;
  void (*fun)();
} max_align_t;

No, the C standard leaves alignment at the discression of the compiler.

In practice, many compilers will align the struct 8-byte aligned, but they are not required to do so.


Need Your Help

Best way to implement Socket.io in android

java android sockets socket.io android-lifecycle

I am planning to implement Socket.io in android by this library for a chat based application. As far as I understood the library seems to be pretty good. I want to know how to maintain a single soc...

android restricting apk install for small screens

android android-manifest apk

How can I restrict my apk to not install on small devices, I know about the support-screens parameter but as I understand correctly , it won't work if user is installing directly from apk.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.