Is it possible to pack a local variable with particular alignment?

Viewed 211

code:

#include <stdio.h>
int main() {
    int a;
    printf("%p\n", &a);
    char b[10];
    printf("%p\n", &b);
    int c;
    printf("%p\n", &c);
}

outputs:

0061fefc
0061fef2
0061feec

It is obvious that b occupies 12 bytes memory becuase the default memory alignment makes the start address of c is a multiple of 4. It is possible to disable the memory alignment? I know #pragma pack can pack a structure, can it pack a local variable to make b occupy only 10 bytes? This is an interview question that makes me interested. Any help will be appreciated!

2 Answers

The C standard does not provide any facility to request relaxed alignment of objects, and there is little or no value in such a feature for independent objects (objects that are not members of a structure).

Structures are sometimes packed, using extensions to standard C, because the bytes in them need to be laid out consecutively for some specific use, such as transmitting them in a network message, or because padding in them may waste large amounts of space when a great many instances of the structure are held in memory. No such purpose occurs with a single independent object.

The char array shown does not occupy twelve bytes. It occupies ten bytes. The other two bytes are either unused or are used by the compiler for other purposes not evident in the addresses examined. In a structure, padding bytes are reserved—held unavailable for other use—to give the desired alignment. In this situation, bytes may have been skipped to give the desired alignment, but they are not reserved for that purpose. If a two-byte object were needed, the compiler could insert it into those bytes.

The amount of stack space wasted due to alignment requirements is generally small because, unlike with structure members, the compiler is free to rearrange objects to use space efficiently. And the stack pointer generally must still satisfy alignment requirements of the application binary interface (ABI), so some space for alignment may still be needed regardless of the alignment requirements of objects on the stack.

Variable packing is an implementation-defined feature. So there is no standard way to do it.

Also I don't think it is possible with GCC, clang or MSVC.

  • alignas and __attribute__ ((aligned)) can increase but not decrease alignment.

  • __attribute__ ((packed)) and #pragma pack don't seem to work outside structs, even though GCC documentation suggests otherwise:

The packed attribute specifies that a variable or structure field should have the smallest possible alignment...

#include <stdio.h>
int main() {
    int a;
    printf("%p\n", &a);
    __attribute__ ((packed)) char b[10];
    printf("%p\n", &b);
    __attribute__ ((packed)) int c;
    printf("%p\n", &c);
}

Output:

warning: ‘packed’ attribute ignored [-Wattributes]
     __attribute__ ((packed)) char b[10];
                                       ^
warning: ‘packed’ attribute ignored [-Wattributes]
     __attribute__ ((packed)) int c;
                                  ^

Clang output a similar warning. MSVC silently ignores #pragma pack there.

All in all it's a poor interview question because it's too specific; there is little, if any, correlation between knowing this and being a good programmer. Though sometimes questions like this are used to probe one's tolerance for stress :)

Related