question about alignment

G

gaoqiang

Is there any alignment requirement in C99 standard for basic object ?
to say, requires an int object to be aligned by sizeof(int) bytes ?
 
K

Kleuske

Is there any alignment requirement in C99 standard for basic object ? to
say, requires an int object to be aligned by sizeof(int) bytes ?

Not from the standard, though various hardware platforms may require proper
alignment.
 
E

Eric Sosman

Is there any alignment requirement in C99 standard for basic object ?
to say, requires an int object to be aligned by sizeof(int) bytes ?

We can deduce that the alignment for a type T is a divisor
of sizeof(T), but we do not know which divisor: 1, sizeof(T)
itself, or something in between.

If you need to discover T's alignment, I know of two approaches:
One is imperfect but available in both the C99 and C90 versions of
the language, the other is perfect but requires a C11 implementation:

- For C99 and C90, you can declare a struct with a char as its
first element and a T as its second, then use the offsetof
macro to find the distance from the start of the struct to the
T element. If T needs stricter-than-char alignment, the T
element will be preceded by padding bytes, and offsetof will
reveal how many were needed. A perverse compiler might use
more padding than required (leading you to think the alignment
is stricter than it actually is), but that seems unlikely.

- For C11, you can use _Alignof(T) to discover the alignment of
any complete type. C11 also has an _Alignas keyword that
allows you to request stricter alignment than is required.
 
J

James Kuyper

Is there any alignment requirement in C99 standard for basic object ?
to say, requires an int object to be aligned by sizeof(int) bytes ?

The C standard allows an implementation to have an alignment requirement
for any given object type, which must be a positive integer. Because of
the way pointer arithmetic and array declarations work, you can infer
the requirement that sizeof(T) is an integer multiple of the alignment
requirement for type T. However, the standard itself does not impose any
other constraints on alignment requirements.

C99 is no longer the current version of the C standard. In the current
version, C2011, there's a number of new alignment oriented features.
Alignments are now required to be non-negative integer powers of 2. I'd
be surprised if there were any implementations of C99 where that wasn't
already true, but it's now mandatory. _Alignof(T) gives the alignment
requirement for a given type. _Alignas(N) can be inserted in the
declaration of an object to indicated that it should have an alignment
that is a multiple of N. _Alignas(T), where T is a typename, is
equivalent to _Alignas(_Alignof(T)).

The new standard header <stdalign.h> introduces macros named alignas,
alignof, __aligas_is_defined and __alignof_is_define which expand to
_Alignas, _Alignof, 1, and 1, respectively. <stddef.h> now defines a
type named max_align_t "which is an object type whose alignment is as
great as is supported by the implementation in all contexts". <stdlib.h>
now defined a function named aligned_alloc() which allows you to specify
the alignment requirement for the memory to be allocated.
 
N

Nobody

A perverse compiler might use more padding than required
(leading you to think the alignment is stricter than it actually
is), but that seems unlikely.

A compiler may align based upon what is optimal rather than what's
strictly required.

E.g. ia32 (i386 and compatible) ABIs invariably have "int" aligned to a
4-byte boundary, although the CPU doesn't require this.
 
S

Shao Miller

Is there any alignment requirement in C99 standard for basic object ?
to say, requires an int object to be aligned by sizeof(int) bytes ?

The alignment of any character type is 1.

The following macro is an example of what Mr. E. Sosman mentioned
else-thread. It is derived from a macro by Mr. Chris M. Thomasson.

#include <stddef.h>
#define AlignOf(type_) (offsetof(struct { char c; type_ t; }, t))

Note that this macro has some light challenges:

- The 'type_' argument must be a simple type-name, suitable for the
'struct' member definition 'type_ t'. For example 'char (*)[10]' is not
such a simple type; you can't have 'char (*)[10] t'.

- Some compilers warn about tagless 'struct' definitions.

- The following equality is not guaranteed for any type 'typename':
'AlignOf(typename) == AlignOf(typename)', since after expansion, there
are two distinct 'struct' types that are not the same type. It's
probably pretty unlikely that a compiler will cause this problem. If
you trust that the alignment will not exceed the range of values for an
'int', you can use:

enum { AlignOfFoo = AlignOf(Foo) };

to ensure that you have an 'AlignOfFoo' value that is an integer
constant expression. That's kind of ugly, but oh well.

As far as I know, in C11, an alignment value must be a power of two.
That makes it pretty unlikely that there was any non-power-of-two
alignment for any pre-C11 implementation. Believing that, if you find
the integer factors for 'sizeof (type)' and the only factors are '1' and
'sizeof (type)', then the alignment requirement must be one or the
other. If you only have these two choices, and if 'sizeof (type) &
(sizeof (type) - 1)' is non-zero, then 'sizeof (type)' is not a power of
two and you're pretty safe believing the alignment requirement is thus '1'.

I believe a portable alignment strategy for pre-C99 where one wishes to
have a variably-sized array following some fixed-sized header is to do
something like:

#include <stddef.h>
#include <stdlib.h>

/* Object types */
typedef int elementtype;
struct s_counted_array;
struct s_aligned_counted_array;

/* Function declarations */
static void * new_counted_array(size_t);

/* Struct/union definitions */
struct s_counted_array {
size_t count;
elementtype * array;
};

/* Function definitions */
int main(void) {
struct s_counted_array * my_array;

/* Allocate a counted array with 42 elements */
my_array = new_counted_array(42);
if (!my_array) {
/* Allocation failed */
return EXIT_FAILURE;
}

/*
* Use the counted array. Assign to
* the last element, for example
*/
my_array->array[my_array->count - 1] = 13;

/* Deallocate the whole thing */
free(my_array);

return EXIT_SUCCESS;
}

static void * new_counted_array(size_t count) {
struct s_aligned_counted_array {
struct s_counted_array header[1];
elementtype a[1];
};
register const size_t offset =
offsetof(struct s_aligned_counted_array, a);
void * memory;
struct s_counted_array * obj;

if (!count) {
/* Don't allocate for 0 elements */
return NULL;
}

obj = memory = malloc(offset + count * sizeof obj->array[0]);
if (memory) {
/*
* Allocation succeeded. Point
* the 'array' member to the array
*/
obj->array = (void *) ((char *) memory + offset);

/* And note the count of elements */
obj->count = count;
}

return obj;
}
 
E

Eric Sosman

A compiler may align based upon what is optimal rather than what's
strictly required.

E.g. ia32 (i386 and compatible) ABIs invariably have "int" aligned to a
4-byte boundary, although the CPU doesn't require this.

It comes down to how you define "required." As an extreme
example, imagine a hardware platform on which everything wider
than `char' required 256-byte alignment. Even on this super-
strict hardware a compiler could use no padding bytes at all,
by copying unaligned data to and from an aligned "staging area"
on every access. This would probably slow things down a lot, but
the implementation could work correctly -- so 256-byte alignment,
even though dictated by the hardware, would not be "required."

Or to return to your example: It's my understanding that on
most IA32 implementations it is possible to access a `double' on
any 4-byte boundary, but faster if it's also on an 8-byte boundary.
Which alignment should a compiler "require?"
 
M

Malcolm McLean

     Or to return to your example: It's my understanding that on
most IA32 implementations it is possible to access a `double' on
any 4-byte boundary, but faster if it's also on an 8-byte boundary.
Which alignment should a compiler "require?"
Eight.
Almost always you want the faster option, rather than saving a few
bytes of memory.
 
H

Harald van Dijk

A compiler may align based upon what is optimal rather than what's
strictly required.

E.g. ia32 (i386 and compatible) ABIs invariably have "int" aligned to a
4-byte boundary, although the CPU doesn't require this.

Whether the CPU requires this is an option, and I have done
experiments with a fully functional x86 system that had that option
turned on. Admittedly this option is disabled by default and not
normally enabled by the OS.
 
K

Kleuske

Eight.
Almost always you want the faster option, rather than saving a few bytes
of memory.

That depends heavily on context. In embedded software, i'd gladly sacrifice
some speed to save memory.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Alignment (K&R question) 13
alignment shame (?) 14
Alignment problems 20
Alignment of foo[1][1][1][1] 41
malloc and alignment question 8
Alignment in Struct 7
Alignment, Cast 27
gcc alignment options 19

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top