2014-12-02 3 views
1

Рассмотрим следующую структуру данных:Как вычислить значение времени компиляции, используя размер членов профсоюзов?

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
  1. Использование decltype (C++ 11 и выше):

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

    На coliru: http://coliru.stacked-crooked.com/a/b566a890b4143838

  2. Вы можете избежать необходимости decltype называя анонимного типа data.

  3. Вы можете использовать тот факт, что sizeof -operand всегда unevaluated, чтобы избежать временных объектов, даже если вы не можете использовать decltype (работает даже на древних составителей):

    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

Имейте в виду, что гибкие массивы-члены являются особенностью C99 даже не в C++ 14, хотя (GCC и лязг принять его как расширение).

+0

Я смущен вашим последним комментарием. Вы говорите, что это решение будет * не * работать с C++? – merlin2011

+0

Я говорю, что массив-элемент без длины не является основным C++, но C99. Тем не менее, он принят как расширение многими реализациями, поэтому вы можете использовать его. – Deduplicator

+0

О, я вижу. Спасибо за уточнение. – merlin2011

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()); 

} 
+0

Имейте в виду, что ваша не является константой времени компиляции, если вы не добавите 'constexpr' (C++ 11). Если вы это сделаете, вы можете использовать 'decltype' просто отлично. – Deduplicator

Смежные вопросы