هل يمكنني التسبب في خطأ في "عدد قليل جدًا من المهيئات"؟
-
01-10-2019 - |
سؤال
أنا أستخدم مُعمى إجمالي لإعداد كتلة من البيانات الثابتة لاختبار الوحدة.
أرغب في استخدام حجم الصفيف كعدد متوقع للعناصر ، ولكن قد يفشل هذا إذا تم توفير عدد قليل جدًا من عمليات التهيئة:
my_struct_type expected[14] =
{
{ 1.234, 0, 'c' },
{ 3.141, 1, 'z' },
{ 2.718, 0, 'a' }
};
هذا لا يعطي أي خطأ في برنامج التحويل البرمجي في Visual Studio 2008.
أود أن أكون قادرًا على استخدامه على هذا النحو:
const unsigned expected_size = sizeof(expected) / sizeof(my_struct_type);
BOOST_CHECK_EQUAL(points.size(), expected_size);
for( int i = 0; i < expected_size; i++ )
{
BOOST_CHECK_EQUAL(points[i].value, expected[i].value);
BOOST_CHECK_EQUAL(points[i].count, expected[i].count);
BOOST_CHECK_EQUAL(points[i].sym, expected[i].sym);
}
ولكن لأنه ليس لدي ضمان وقت الترجيح بـ 14 نقطة ، فإن هذا ينطلق من نهاية الصفيف نهاية القيم المقدمة وإلى القيم الافتراضية.
هل يمكنني فرض عدد المهيئات المهيمنة في وقت الترجمة؟
المحلول
أولاً: قد يكون هناك تحذير لهذا. هل حاولت التجميع على أعلى مستوى تحذير؟
ثم: إذا قمت بتبديل القيمة التي يتم حسابها والتي تكون حرفية ، فيمكنك رفع خطأ في وقت الترجمة:
my_struct_type my_array[] = // <== note the empty []
{
{ 1.234, 0, 'c' },
{ 3.141, 1, 'z' },
{ 2.718, 0, 'a' }
};
BOOST_STATIC_ASSERT( sizeof(my_array)/sizeof(my_array[0]) == 14 );
نصائح أخرى
في الواقع ، لن يركض نهاية الصفيف ، لأن المترجم سيؤدي إلى إضعاف جميع عناصر الصفيف التي لم تهيئها بنفسك.
إذا كنت تحاول التأكد من أن لديك عددًا محددًا من المهيئات التي تم تكوينها ، لست متأكدًا من كيفية القيام بذلك.
إذا كنت تريد فقط التأكد من أن الصفيف هو عدد العناصر التي لديك:
my_struct_type expected[] =
{
{ 1.234, 0, 'c' },
{ 3.141, 1, 'z' },
{ 2.718, 0, 'a' }
};
سوف تفعل الحيلة. ثم استخدم فقط sizeof(expected) / sizeof(expected[0])
للحصول على إجمالي عدد عناصر الصفيف.
فقط من أجل إجابة غير عازمة ...
يمكنك إضافة متطلبات التهيئة عن طريق التعديل my_struct_type
.
template< typename T >
struct must_be_initialized {
T value;
must_be_initialized( T const &v ) : value( v ) {}
// no default constructor!
operator T& () { return value; }
operator T const& () const { return value; }
};
struct my_struct_type {
must_be_initialized< double > f;
int i;
char c;
};
my_struct_type expected[14] =
{
{ 1.234, 0, 'c' },
{ 3.141, 1, 'z' },
{ 2.718, 0, 'a' }
// error: no default constructor exists
};
my_struct_type
لا يزال مجموع ، لكنه ليس جراب.
ISO/IEC 14882 (الإصدار الأول 1998-09-01) في ص. 8.5.1.7 ينص على ما يلي:
إذا كان هناك عدد أقل من المهيمنات في القائمة أكثر من وجود أعضاء في الإجمالي ، فإن كل عضو لم يتم تهيئته بشكل صريح يجب أن يكون افتراضيًا (8.5). [مثال: struct s {int a ؛ شار* ب ؛ int c ؛ } ؛ s ss = {1 ، "asdf"} ؛ تهيئة Ss.a مع 1 ، Ss.B مع "ASDF" ، و Ss.C مع قيمة تعبير النموذج int () ، أي 0.
ببساطة ، إجابة سؤالك هي لا.
بحسب ال MSDN, ، إذا تم تحديد عدد أقل من المهيئات ، يتم تهيئة العناصر المتبقية مع 0 ، لذلك يجب أن يعمل الرمز مع ذلك.