سؤال

هل هناك طريقة موثوقة لإعلان typedefs لأنواع عدد صحيح من 8،16،32 الثابتة ، وطول 64 بت في ISO Standard C؟

عندما أقول ISO Standard C ، أعني ذلك بدقة:

  • ISO C89/C90 ، وليس C99.
  • لا توجد رؤوس غير محددة في معيار ISO.
  • لا توجد رموز مسبقة غير محددة في معيار ISO.
  • لا توجد افتراضات بحجم النوع غير محدد في معيار ISO.
  • لا رموز بائع الملكية.

أرى أسئلة أخرى مشابهة لهذا في Stackoverflow ، ولكن لا توجد إجابات بعد لا تنتهك أحد القيود المذكورة أعلاه. لست متأكدًا من أنه ممكن دون اللجوء إلى رموز المنصة.

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

المحلول

نعم تستطيع.

ملف الرأس limits.h يجب أن يكون جزءا من C90. ثم سأختبر من خلال قيم توجيهات المعالج المسبق SHRT_MAX, INT_MAX, LONG_MAX, ، و LLONG_MAX وتعيين typedefs وفقا لذلك.

مثال:

#include <limits.h>

#if SHRT_MAX == 2147483647
typedef unsigned short int uint32_t;
#elif INT_MAX == 2147483647
typedef unsigned int uint32_t;
#elif LONG_MAX == 2147483647
typedef unsigned long uint32_t ;
#elif LLONG_MAX == 2147483647
typedef unsigned long long uint32_t;
#else
#error "Cannot find 32bit integer."
#endif

نصائح أخرى

بالمعنى الدقيق للكلمة ، ISO 9899: 1999 ISO 9899: 1990 ، فهو مواصفات لغة ISO القياسية الحالية الوحيدة.

نظرًا لأن الأسماء الدقيقة للطباعة لأنواع عدد صحيح تم تقديمها فقط في المعيار في إصدار 1999 ، فإن ما تريده غير ممكن باستخدام إصدار 1990 فقط من المعيار.

لا يوجد. هناك طريقة موثوقة لإعلان متغيرات عدد صحيح فردي يصل إلى 32 بت ، ومع ذلك ، إذا كنت على استعداد للعيش مع بعض القيود. فقط استخدم long Bitfields (يُضمن أن يكون هذا الأخير على الأقل 32 بت ، ويُسمح لك باستخدام ما يصل إلى عدد أكبر من البتات في حقل Bitfields كما هو مناسب للمتغير إذا تم حذف إعلان Bitfield). لذا:

struct {
   unsigned long foo : 32; 
} bar;

من الواضح أنك تحصل على كل القيود التي تأتي مع ذلك ، مثل عدم القدرة على الحصول على مؤشرات لمثل هذه المتغيرات. الشيء الوحيد الذي يشتريه حقًا يضمن لك التفاف عند الحدود المحددة على التدفق الزائد/السفلي ، وحتى ذلك الحين فقط لأنواع غير موقعة ، نظرًا لأن الفائض غير محدد للتوقيع.

بصرف النظر عن ذلك ، لا توجد طريقة محمولة للقيام بذلك في C90 النقي. من بين أشياء أخرى ، لا يحتاج تطبيق C90 المطابق إلى عدد صحيح 8 بت ، على سبيل المثال - سيكون من القانوني تمامًا أن يكون لديك منصة sizeof(char) == sizeof(short) == sizeof(int) == 1 و CHAR_BIT == 16 (أي أنه يحتوي على كلمة آلة 16 بت ، ولا يمكنها معالجة البايتات الفردية). لقد سمعت أن مثل هذه المنصات موجودة في الواقع في الممارسة العملية في شكل بعض DSPs.

هناك خطر مع مثل هذه الأساليب عند استخدام المجمعين الحديثين هو أنه أصبح من المألوف للمترجمين افتراض أن مؤشر نوع عدد صحيح لن يتم استخدامه للوصول إلى قيم أخرى ، حتى عندما يكون كلا النوعين نفس الحجم والتمثيل. إذا كان هناك نوعان لهما نفس الحجم والتمثيل ، واختار كل منهما جزءًا من البرنامج نفسه أحدهما ، بتطبيق تحسينات وقت الارتباط على البرامج التي تشارك المؤشرات في مثل هذه البيانات قد يؤدي إلى سلوك غير لائق. بالنسبة لبعض التطبيقات على العديد من الأنظمة ، سيكون هناك حجم واحد على الأقل من عدد صحيح سيكون من المستحيل إعلان مؤشر يمكن استخدامه بأمان للوصول إلى جميع قيم عدد صحيح بهذا الحجم ؛ على سبيل المثال على الأنظمة حيث كلاهما long و long long 64 بت ، لن تكون هناك طريقة لإعلان مؤشر يمكن استخدامه بشكل موثوق للوصول إلى البيانات من أي نوع بالتبادل.

لا ، لا يمكنك فعل ذلك.

الآن ، إذا كنت ترغب في حساب عملية تكوين متعددة المراحل مثل GNU configure كحل ، يمكنك القيام بذلك والتمسك بـ C89. وهناك بالتأكيد أنواع مختلفة يمكنك استخدامها نكون في C89 ، وسيؤدي ذلك إلى DTRT على كل تطبيق تقريبًا موجود اليوم ، بحيث تحصل على الأحجام التي تريدها وتتمسك بها مع C89 النقي. لكن عرض البتات ، في حين أن ما تريده ، لن يتم تحديده بشكل عام وفقًا للمعيار.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top