如何使用联合成员的大小计算编译时值?

时间:2014-12-02 18:38:38

标签: c++

考虑以下数据结构:

union LambdaBox {                                                           
    struct {                                                                
        uint64_t full;                                                      
        char lambda[];                                                      
    } data;                                                                 
    char padding[64];                                          
};                                                                          

成员变量full的大小在编译时是清楚已知的。

如果没有先创建LambdaBox类型的对象,我该如何直接引用它?

更具体地说,我试图编写一个表达式(在编译时计算),它在语义上等同于下面的第三个语句。

int main(){
    // This works
    printf("The total size allowed is %zu\n", 56L);
    // This also works
    printf("The total size of LambdaBox is %zu\n", sizeof(LambdaBox));

    // What is the correct syntax for the semantic meaning of the following line?
    printf("The total size allowed is %zu\n", sizeof(LambdaBox) -
            sizeof(LambdaBox::data::full);
}

2 个答案:

答案 0 :(得分:2)

  1. 使用decltype(C ++ 11及更高版本):

    sizeof(LambdaBox) - sizeof decltype(LambdaBox::data)::full
    

    关于coliru:http://coliru.stacked-crooked.com/a/b566a890b4143838

  2. 您可以通过命名匿名类型decltype来避免data的需要。

  3. 即使您不能使用sizeof(即使在古代编译器上工作),您也可以使用decltype - 操作数始终为unevaluated以避免临时的事实:

    sizeof(LambdaBox) - sizeof LambdaBox().data.full
    

    关于coliru:http://coliru.stacked-crooked.com/a/14bcbd6995c9dd8c

  4. 直接的方式:

    sizeof(LambdaBox) - sizeof LambdaBox::data.full
    

    关于coliru:http://coliru.stacked-crooked.com/a/f984d8e9462ca2c2

  5. 请注意灵活的阵列成员是C99功能,但即使在C ++ 14中也是如此(GCC和clang接受它作为扩展)。

答案 1 :(得分:0)

以下是我发现的一种不使用C ++ 11功能的解决方法,我的编译器g++ 4.4.7并不完全支持这些功能。

#include <stdint.h>
#include <stdio.h>


union LambdaBox {                                                           
    struct {                                                                
        uint64_t full;                                                      
        char lambda[];                                                      
    } data;                                                                 
    char padding[64];                                          

    static uint64_t getMaxSize() { 
        return sizeof(LambdaBox) - sizeof(data.full);  
    }                              

};                                                                          

int main(){
    printf("The total size allowed is %zu\n", 56L);
    printf("The total size of LambdaBox is %zu\n", sizeof(LambdaBox));

    printf("The total size allowed is %zu\n", LambdaBox::getMaxSize());

}