Is it always the case that sizeof(T) >= alignof(T) for all object types T?

后端 未结 4 1583
抹茶落季
抹茶落季 2020-12-05 01:51

For any object type T is it always the case that sizeof(T) is at least as large as alignof(T)?

Intuitively it seems so, since

相关标签:
4条回答
  • 2020-12-05 02:37

    According to the c++ 11 standard that introduced the alignof operator, sizeof is defined as following (see 5.3.3 expr.sizeof):

    The sizeof operator yields the number of bytes in the object representation of its operand

    Whereas alignof definition is (see 5.3.6 expr.alignof):

    An alignof expression yields the alignment requirement of its operand type.

    Since the defintion of alignof specifies a requirement, possibly made by the user, rather than a specification of the language, we can manipulate the compiler:

    typedef uint32_t __attribute__ ((aligned (64))) aligned_uint32_t;
    std::cout << sizeof(aligned_uint32_t) << " -> " << alignof(aligned_uint32_t);
    // Output: 4 -> 64
    

    Edited

    As others have pointed out, such types cannot be used in arrays, e.g trying to compile the following:

    aligned_uint32_t arr[2];
    

    Results in error: alignment of array elements is greater than element size

    Since arrays require the specified type to conform with the condition: sizeof(T) >= alignof(T)

    0 讨论(0)
  • 2020-12-05 02:38
    #include <iostream>
    
    typedef double foo __attribute__ ((aligned (64)));
    alignas(64) double bar;
    double baz __attribute__ ((aligned (64)));
    
    int main(int argc, char *argv[]) {
        std::cout << "foo sizeof: " << sizeof(foo) << " alignof: " << alignof(foo) << "\n";
        std::cout << "bar sizeof: " << sizeof(bar) << " alignof: " << alignof(decltype(bar)) << "\n";
        std::cout << "baz sizeof: " << sizeof(baz) << " alignof: " << alignof(decltype(baz)) << "\n";
    }
    

    Compile with:

    clang++ -std=c++11 alignof_test.cpp -o alignof_test && ./alignof_test
    

    Output:

    foo sizeof: 8 alignof: 64
    bar sizeof: 8 alignof: 8
    baz sizeof: 8 alignof: 8
    

    So strictly speaking, no, but the above argument re: arrays has to be preserved.

    0 讨论(0)
  • 2020-12-05 02:39

    At least in standard C++, for anything you can make an array of (with length > 1), this will have to be true. If you have

    Foo arr[2];
    

    and alignof(Foo) > sizeof(Foo), then arr[0] and arr[1] can't both be aligned.

    As Zalman Stern's example shows, though, at least some compilers will allow you to declare a type with alignment greater than its size, with the result that the compiler simply won't let you declare an array of that type. This is not standards-compliant C++ (it uses type attributes, which are a GCC extension), but it means that you can have alignof(T) > sizeof(T) in practice.

    The array argument assumes sizeof(Foo) > 0, which is true for any type supported by the standard, but o11c shows an example where compiler extensions break that guarantee: some compilers allow 0-length arrays, with 0 sizeof and positive alignof.

    0 讨论(0)
  • 2020-12-05 02:44

    Many compilers allow arrays of size 0. The alignment remains the same as the alignment of the sole element.

    (Among other things, this is useful for forcing a particular alignment in cases when you can't use a bitfield)

    0 讨论(0)
提交回复
热议问题