¿Es esta una forma portátil de hacer que un buffer de stack de ocho bytes se alinee?

struct { uint64_t a; char z[120]; } b; ... struct buffer_with_alignment_requirement* c = (struct buffer_w*)&b; c->start_using_it; 

Sin el primer miembro a , podríamos bloquearnos al acceder a los campos en el búfer. ¿Es portátil y correcto simplemente agregar un miembro como este para forzar la alineación para que toda la estructura sea lo suficientemente estricta?

Esta no es una pregunta sobre el aliasing de punteros, simplemente sobre si la dirección de b en la stack siempre está alineada con ocho bytes.

Depende de lo que quieras decir con alineado. Si desea (uintptr_t)&b % 8 == 0 , no hay una forma portátil de obtener esto, ya que la conversión de puntero a entero está definida por la implementación y no es necesario que sea un mapeo natural y sensato.

Si todo lo que desea es que el búfer esté suficientemente alineado para el acceso con el tipo uint64_t , su solución funciona perfectamente bien. Pero, ¿por qué no usas (posiblemente una matriz de) tipo struct buffer_with_alignment_requirement , en lugar de la fea unión de hackers? En otras palabras, simplemente asigne al búfer el tipo correcto al que desea acceder para comenzar. Puede pasar un puntero a cualquier tipo para read , fread , revc , etc. y otras funciones que podría estar usando para escribir en el búfer, e incluso si lo va a pasar a una función que espera un tipo de puntero de búfer char * o unsigned char * , puedes lanzarlo al pasarlo; Este elenco está perfectamente definido y válido.

Los tipos de enteros de ancho exacto, si existen (7.20.1.1p3), no tienen requisitos de alineación particulares distintos a los que deberían estar al menos tan alineados como char y no más alineados que max_align_t (6.2.8p2-4). Ni siquiera existe el requisito de que la alineación deba seguir el rango de conversión de enteros, excepto, por supuesto, que los tipos con signo y sin signo correspondientes deben tener la misma alineación (6.2.5p6).

Si desea una alineación particular, use un especificador de alineación:

 #include  struct alignas(8) { char z[120]; } b; 

Sin embargo, presumiblemente, dada su descripción de los campos de acceso, lo que realmente desea es que el búfer se alinee con el tipo más alineado que pueda existir dentro del búfer. Para ello, C11 proporciona max_align_t ; en comstackdores más antiguos puedes emular max_align_t usando una unión de los tipos estándar:

 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, el estándar C deja la alineación en la discresión del comstackdor.

En la práctica, muchos comstackdores alinearán la estructura de 8 bytes alineada, pero no están obligados a hacerlo.