ما هو ماكرو المشترك C / C ++ لتحديد حجم لأحد أعضاء هيكل؟

StackOverflow https://stackoverflow.com/questions/1400660

  •  05-07-2019
  •  | 
  •  

سؤال

في C / C ++، كيف يمكنني تحديد حجم المتغير عضو إلى هيكل دون الحاجة إلى تعريف متغير وهمية من هذا النوع هيكل؟ وإليك مثال على كيفية القيام بذلك على نحو خاطئ، ولكن يظهر القصد:

typedef struct myStruct {
  int x[10];
  int y;
} myStruct_t;

const size_t sizeof_MyStruct_x = sizeof(myStruct_t.x);  // error

لمرجعية، وينبغي أن يكون هذا كيفية العثور على حجم 'س' إذا قمت أولا تعريف متغير وهمية:

myStruct_t dummyStructVar;

const size_t sizeof_MyStruct_x = sizeof(dummyStructVar.x);

ولكن، وأنا على أمل لتجنب الاضطرار إلى إنشاء متغير وهمية فقط للحصول على حجم 'س'. أعتقد أن هناك وسيلة ذكية لإعادة صياغة 0 كما myStruct_t للمساعدة في العثور على حجم متغير العضو 'س'، ولكن انها كانت طويلة بما يكفي أنني نسيت التفاصيل، ويمكن أن يبدو للحصول على جوجل للبحث جيد على هذا . هل تعلم؟

وشكرا!

هل كانت مفيدة؟

المحلول

في C ++ (وهو ما تقول به)، يمكن استبدال التعليمات البرمجية "متغير وهمية" مع:

sizeof myStruct_t().x;

وسيتم إنشاء أي كائن myStruct_t: مترجم يعمل فقط من نوع ثابت من المعامل sizeof، فإنه لا يتم تنفيذ التعبير

وهذا يعمل في C، وفي C ++ الأفضل لأنه يعمل أيضا لفئات دون الوصول إلى عدم وسائط المنشئ:

sizeof ((myStruct_t *)0)->x

نصائح أخرى

وأنا باستخدام الماكرو التالي:

#include <iostream>
#define DIM_FIELD(struct_type, field) (sizeof( ((struct_type*)0)->field ))
int main()
{
    struct ABC
    {
        int a;
        char b;
        double c;
    };
    std::cout << "ABC::a=" << DIM_FIELD(ABC, a) 
              << " ABC::c=" << DIM_FIELD(ABC, c) << std::endl;

    return 0;
}

والخديعة هو علاج 0 كما مؤشر إلى البنية الخاصة بك. يتم حل هذا في وقت الترجمة بحيث أنها آمنة.

ويمكنك القيام بذلك بسهولة

sizeof(myStruct().x)

وكما يتم تنفيذ المعلمة sizeof أبدا، ليس عليك حقا إنشاء هذا الكائن.

وأي من هذه يجب أن تعمل:

sizeof(myStruct_t().x;);

أو

myStruct_t *tempPtr = NULL;
sizeof(tempPtr->x)

أو

sizeof(((myStruct_t *)NULL)->x);

ولأن يتم تقييم sizeof في الترجمة من الوقت، لا وقت التشغيل، سوف لا يكون لديك مشكلة dereferencing مؤشر NULL.

في C ++ 11، وهذا يمكن أن يتم ذلك مع sizeof(myStruct_t::x). C ++ 11 يضيف أيضا الأمراض المنقولة جنسيا :: declval ، والتي يمكن استخدامها لهذا (من بين أمور أخرى):

#include <utility>
typedef struct myStruct {
  int x[10];
  int y;
} myStruct_t;

const std::size_t sizeof_MyStruct_x_normal = sizeof(myStruct_t::x);
const std::size_t sizeof_MyStruct_x_declval = sizeof(std::declval<myStruct_t>().x);

من وجهة نظري رأس وحدات الماكرو فائدة:

#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))

والتذرع مثل ذلك:

FIELD_SIZE(myStruct_t, x);  
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top