هل هناك أي سبب لاستخدام ج بدلا من C++ جزءا لا يتجزأ من التنمية ؟

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

  •  03-07-2019
  •  | 
  •  

سؤال

السؤال

لدي اثنين من المجمعين على الأجهزة C++ و C89

أنا أفكر باستخدام C++ مع الطبقات ولكن دون تعدد الأشكال (لتجنب vtables).الأسباب الرئيسية التي أود أن استخدام C++ هي:

  • أنا أفضل أن استخدام "مضمن" وظائف بدلا من تعريفات الماكرو.
  • أود أن استخدام مساحات وأنا البادئات فوضى رمز.
  • أرى C++ نوع قليلا أكثر أمنا وذلك أساسا بسبب قوالب و مطول الصب.
  • أنا حقا أحب طاقتها وظائف والمنشئات (المستخدمة في الصب الآلي).

هل ترى أي سبب التمسك C89 عند وضع جدا من الأجهزة المحدود (4 كيلوبايت من ذاكرة الوصول العشوائي)?

الختام

شكرا لك على إجاباتك ، كانت مفيدة حقا!

اعتقد ان هذا الموضوع من خلال وسأصر ج وذلك بسبب:

  1. فمن السهل التنبؤ الفعلية البرمجية في C و هذا هو المهم حقا إذا كان لديك فقط 4 كيلوبايت من ذاكرة الوصول العشوائي.
  2. فريقي يتكون أساسا من ج المطورين ، لذلك المتقدمة C++ الميزات لن يكون استخداما.
  3. لقد وجدت طريقة وظائف مضمنة في برنامج التحويل البرمجي C (C89).

فمن الصعب أن تقبل إجابة واحدة كما يمكنك توفير الكثير من إجابات جيدة.للأسف لا أستطيع إنشاء ويكي و تقبل لذا سوف تختار إجابة واحدة أن جعلني أفكر أكثر.

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

المحلول

هناك سببان لاستخدام C بدلاً من C++:

  1. بالنسبة للعديد من المعالجات المضمنة، إما أنه لا يوجد مترجم C++، أو يتعين عليك دفع مبلغ إضافي مقابل ذلك.
  2. تجربتي هي أن نسبة كبيرة من مهندسي البرمجيات المضمنة لديهم خبرة قليلة أو معدومة في لغة C++ - إما بسبب (1)، أو لأنه لا يتم تدريسها في درجات الهندسة الإلكترونية - ولذا سيكون من الأفضل الالتزام بها ما يعرفونه.

كما أن السؤال الأصلي وعدد من التعليقات يذكر 4 كيلو بايت من كبش.بالنسبة للمعالج المدمج النموذجي، لا يرتبط مقدار ذاكرة الوصول العشوائي (في الغالب) بحجم الكود، حيث يتم تخزين الكود وتشغيله من الفلاش.

من المؤكد أن مقدار مساحة تخزين التعليمات البرمجية هو أمر يجب أخذه في الاعتبار، ولكن مع ظهور معالجات جديدة وأكثر سعة في السوق، أصبحت المشكلة أقل مما كانت عليه في جميع المشاريع باستثناء المشاريع الأكثر حساسية من حيث التكلفة.

حول استخدام مجموعة فرعية من C++ للاستخدام مع الأنظمة المدمجة:هناك الآن أ ميسرة سي ++ المعيار، والذي قد يكون يستحق نظرة.

يحرر: أنظر أيضا هذا السؤال, مما أدى إلى جدل حول C مقابل C++ للأنظمة المدمجة.

نصائح أخرى

ل جداً مع هدف محدود الموارد مثل 4 كيلو بايت من ذاكرة الوصول العشوائي (RAM)، سأختبر الأمر ببعض العينات قبل بذل الكثير من الجهد الذي لا يمكن إعادته بسهولة إلى تطبيق ANSI C خالص.

اقترحت مجموعة عمل Embedded C++ مجموعة فرعية قياسية من اللغة ومجموعة فرعية قياسية من المكتبة القياسية لتتوافق معها.لقد فقدت مسار هذا الجهد عندما ماتت مجلة مستخدم C، لسوء الحظ.يبدو أن هناك مقال في ويكيبيديا, ، وأن لجنة لا يزال موجودا.

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

لن تسبب الوظائف المضمنة الكثير من المشاكل، إلا إذا كانت كبيرة بما يكفي لتكون وظائف حقيقية في المقام الأول.بالطبع وحدات الماكرو التي حلت محلها كانت لها نفس المشكلة.

قد لا تتسبب القوالب أيضًا في حدوث مشكلة ما لم يكن إنشاء مثيل لها مسعورًا.بالنسبة لأي قالب تستخدمه، قم بمراجعة التعليمات البرمجية التي تم إنشاؤها (قد تحتوي خريطة الارتباط على أدلة كافية) للتأكد من حدوث عمليات المثيل التي كنت تنوي استخدامها فقط.

إحدى المشكلات الأخرى التي قد تنشأ هي التوافق مع مصحح الأخطاء الخاص بك.ليس من غير المعتاد أن يتمتع مصحح أخطاء الأجهزة القابل للاستخدام بطريقة أخرى بدعم محدود للغاية للتفاعل مع كود المصدر الأصلي.إذا كان يجب عليك تصحيح الأخطاء أثناء التجميع بشكل فعال، فإن تغيير الاسم المثير للاهتمام لـ C++ يمكن أن يضيف ارتباكًا إضافيًا إلى المهمة.

RTTI، والقوالب الديناميكية، والميراث المتعدد، وتعدد الأشكال الثقيل، والاستثناءات كلها تأتي مع قدر من تكلفة وقت التشغيل لاستخدامها.هناك عدد قليل من هذه الميزات التي تزيد من تكلفة البرنامج بأكمله إذا تم استخدامها، والبعض الآخر يزيد فقط من وزن الفئات التي تحتاج إليها.تعرف على الفرق، واختر الميزات المتقدمة بحكمة مع المعرفة الكاملة بتحليل سريع للتكلفة/الفائدة على الأقل.

في بيئة مدمجة صغيرة، سيتم إما الارتباط مباشرة بنواة في الوقت الفعلي أو التشغيل مباشرة على الجهاز.وفي كلتا الحالتين، ستحتاج إلى التأكد من أن رمز بدء التشغيل الخاص بك في وقت التشغيل يتعامل مع مهام بدء التشغيل المحددة لـ C++ بشكل صحيح.قد يكون هذا بسيطًا مثل التأكد من استخدام خيارات الرابط الصحيحة، ولكن نظرًا لأنه من الشائع أن يكون لديك تحكم مباشر في المصدر إلى نقطة إدخال الطاقة عند إعادة تعيينها، فقد تحتاج إلى تدقيق ذلك للتأكد من أنه يفعل كل شيء.على سبيل المثال، في منصة ColdFire التي عملت عليها، تم شحن أدوات التطوير مع وحدة CRT0.S التي كانت تحتوي على مُهيئات C++ ولكن تم التعليق عليها.إذا كنت قد استخدمته مباشرة من الصندوق، كنت سأشعر بالحيرة من الكائنات العالمية التي لم يتم تشغيل مُنشئيها على الإطلاق.

أيضًا، في البيئة المضمنة، غالبًا ما يكون من الضروري تهيئة الأجهزة قبل استخدامها، وإذا لم يكن هناك نظام تشغيل ولا أداة تحميل تمهيد، فإن التعليمات البرمجية الخاصة بك هي التي تفعل ذلك.سوف تحتاج إلى أن تتذكر أنه يتم تشغيل مُنشئات الكائنات العامة قبل main() تم استدعاؤه لذا ستحتاج إلى تعديل CRT0.S المحلي (أو ما يعادله) لإنجاز تهيئة الأجهزة قبل يتم استدعاء المنشئين العالميين أنفسهم.ومن الواضح أن الجزء العلوي من main() لقد فات الأوان.

لا.يمكن تجنب أي من ميزات لغة C++ التي يمكن أن تسبب مشاكل (تعدد الأشكال في وقت التشغيل، RTTI، وما إلى ذلك) أثناء إجراء التطوير المضمن.يوجد مجتمع من مطوري C++ المضمنين (أتذكر قراءة أعمدة المطورين المضمنين الذين يستخدمون C++ في مجلة مستخدمي C/C++ القديمة)، ولا أستطيع أن أتخيل أنهم سيكونون صريحين جدًا إذا كان الاختيار بهذا السوء.

ال تقرير فني عن أداء C++ هو دليل عظيم لهذا النوع من الأشياء.لاحظ أنه يحتوي على قسم خاص باهتمامات البرمجة المضمنة!

أيضًا ++ عند ذكر Embedded C++ في الإجابات.المعيار لا يناسب ذوقي بنسبة 100%، ولكنه مرجع جيد عند تحديد أجزاء C++ التي قد تسقطها.

أثناء البرمجة للمنصات الصغيرة، نقوم بتعطيل الاستثناءات وRTTI، وتجنب الميراث الافتراضي، وإيلاء اهتمام وثيق لعدد الوظائف الافتراضية الموجودة لدينا.

صديقك هو خريطة الرابط، على الرغم من:قم بفحصها بشكل متكرر، وسوف تكتشف مصادر التعليمات البرمجية وتتضخم الذاكرة الثابتة بسرعة.

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

أوصي باستخدام مترجم C++، ولكن مع تقييد استخدامك لميزات C++ المحددة.يمكنك البرمجة مثل C في C++ (يتم تضمين وقت تشغيل C عند استخدام C++، على الرغم من أنك في معظم التطبيقات المضمنة لا تستخدم المكتبة القياسية على أي حال).

يمكنك المضي قدمًا واستخدام فئات C++ وما إلى ذلك، فقط

  • الحد من استخدامك للوظائف الافتراضية (كما قلت)
  • الحد من استخدامك للقوالب
  • بالنسبة للنظام الأساسي المضمن، ستحتاج إلى تجاوز عامل التشغيل الجديد و/أو استخدام الموضع الجديد لتخصيص الذاكرة.

باعتباري مهندس نظام ثابت/مضمن، يمكنني أن أخبركم يا رفاق ببعض الأسباب التي تجعل لغة C لا تزال الخيار الأول على C++ ونعم، أنا أتقن كليهما بطلاقة.

1) تحتوي بعض الأهداف التي نقوم بتطويرها على 64 كيلو بايت من ذاكرة الوصول العشوائي لكل من التعليمات البرمجية والبيانات، لذلك عليك التأكد من عدد كل بايت، ونعم، لقد تعاملت مع تحسين التعليمات البرمجية لتوفير 4 بايت مما كلفني ساعتين، وهذا في 2008.

2) تتم مراجعة كل وظيفة في مكتبة C قبل أن نسمح لها بالدخول إلى الكود النهائي، بسبب محدودية الحجم، لذلك نفضل عدم استخدام الأشخاص لقسم (لا يوجد مقسم للأجهزة، لذلك هناك حاجة إلى مكتبة كبيرة)، و malloc (لأنه ليس لدينا كومة ، يتم تخصيص كل الذاكرة من المخزن المؤقت للبيانات في قطعة 512 بايت ويجب مراجعة التعليمات البرمجية)، أو غيرها من الممارسات الموجهة للكائنات التي تحمل عقوبة كبيرة.تذكر أن كل وظيفة مكتبة تستخدمها يتم حسابها.

3) هل سمعت يومًا بمصطلح التراكب؟لديك مساحة صغيرة جدًا من التعليمات البرمجية بحيث تضطر أحيانًا إلى تبديل الأشياء بمجموعة أخرى من التعليمات البرمجية.إذا قمت باستدعاء وظيفة مكتبة، فيجب أن تكون وظيفة المكتبة مقيمة.إذا كنت تستخدمه فقط في وظيفة التراكب، فإنك تهدر الكثير من المساحة بالاعتماد على العديد من الأساليب الموجهة للكائنات.لذلك، لا تفترض قبول أي وظيفة من وظائف مكتبة C، ناهيك عن C++.

4) هناك حاجة إلى الصب وحتى التعبئة (حيث تتقاطع بنية البيانات غير المحاذاة مع حدود الكلمات) بسبب تصميم الأجهزة المحدود (أي.محرك ECC متصل بطريقة معينة) أو للتعامل مع خطأ في الأجهزة.لا يمكنك أن تفترض الكثير بشكل ضمني، فلماذا تعترض على توجيهه أكثر من اللازم؟

5) السيناريو الأسوأ:سيؤدي التخلص من بعض الأساليب الموجهة للكائنات إلى إجبار التطوير على التفكير قبل استخدام الموارد التي يمكن أن تنفجر (على سبيل المثال.تخصيص 512 بايت على المكدس بدلاً من المخزن المؤقت للبيانات)، ومنع بعض السيناريوهات الأسوأ المحتملة التي لم يتم اختبارها أو إزالة مسار التعليمات البرمجية بالكامل معًا.

6) نحن نستخدم الكثير من التجريد لإبعاد الأجهزة عن البرامج وجعل التعليمات البرمجية محمولة قدر الإمكان وسهلة المحاكاة.يجب أن يتم تضمين الوصول إلى الأجهزة في ماكرو أو وظيفة مضمنة يتم تجميعها بشكل مشروط بين نظام أساسي مختلف، ويجب أن يتم تصنيف نوع البيانات كحجم بايت بدلاً من هدف محدد، ولا يُسمح باستخدام المؤشر المباشر (لأن بعض الأنظمة الأساسية تفترض أن الذاكرة المعينة للإدخال / الإخراج هي مثل ذاكرة البيانات)، وما إلى ذلك.

يمكنني التفكير في المزيد، لكنك حصلت على الفكرة.لدينا نحن رجال البرامج الثابتة تدريب موجه للكائنات، ولكن مهمة النظام المضمن يمكن أن تكون موجهة نحو الأجهزة ومنخفضة المستوى، بحيث لا تكون عالية المستوى أو قابلة للتجريد بطبيعتها.

راجع للشغل، كل وظيفة البرامج الثابتة كنت في استخدام التحكم بالمصادر، وأنا لا أعرف من أين حصلت على هذه الفكرة من.

-بعض البرامج الثابتة من شركة سانديسك.

تفضيلي الشخصي هو C لأنه:

  • أعرف ما يفعله كل سطر من التعليمات البرمجية (والتكاليف)
  • لا أعرف C++ جيدًا بما يكفي لمعرفة ما يفعله كل سطر من التعليمات البرمجية (والتكاليف)

لماذا يقول الناس هذا؟أنت لا تعرف على ما يفعله كل سطر من لغة C إلا إذا قمت بفحص إخراج asm.الشيء نفسه ينطبق على C++.

على سبيل المثال، ما الذي ينتج عن هذا البيان البريء:

a[i] = b[j] * c[k];

يبدو بريئًا إلى حد ما، لكن المترجم المعتمد على دول مجلس التعاون الخليجي ينتج هذا ASM لميكرو 8 بت

CLRF 0x1f, ACCESS
RLCF 0xfdb, W, ACCESS
ANDLW 0xfe
RLCF 0x1f, F, ACCESS
MOVWF 0x1e, ACCESS
MOVLW 0xf9
MOVF 0xfdb, W, ACCESS
ADDWF 0x1e, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfa
MOVF 0xfdb, W, ACCESS
ADDWFC 0x1f, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0xfee, 0x1c
NOP
MOVFF 0xfef, 0x1d
NOP
MOVLW 0x1
CLRF 0x1b, ACCESS
RLCF 0xfdb, W, ACCESS
ANDLW 0xfe
RLCF 0x1b, F, ACCESS
MOVWF 0x1a, ACCESS
MOVLW 0xfb
MOVF 0xfdb, W, ACCESS
ADDWF 0x1a, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfc
MOVF 0xfdb, W, ACCESS
ADDWFC 0x1b, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0xfee, 0x18
NOP
MOVFF 0xfef, 0x19
NOP
MOVFF 0x18, 0x8
NOP
MOVFF 0x19, 0x9
NOP
MOVFF 0x1c, 0xd
NOP
MOVFF 0x1d, 0xe
NOP
CALL 0x2142, 0
NOP
MOVFF 0x6, 0x16
NOP
MOVFF 0x7, 0x17
NOP
CLRF 0x15, ACCESS
RLCF 0xfdf, W, ACCESS
ANDLW 0xfe
RLCF 0x15, F, ACCESS
MOVWF 0x14, ACCESS
MOVLW 0xfd
MOVF 0xfdb, W, ACCESS
ADDWF 0x14, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfe
MOVF 0xfdb, W, ACCESS
ADDWFC 0x15, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0x16, 0xfee
NOP
MOVFF 0x17, 0xfed
NOP

يعتمد عدد التعليمات المنتجة بشكل كبير على:

  • الأحجام أ، ب، ج.
  • ما إذا كانت هذه المؤشرات مخزنة على المكدس أم أنها عالمية
  • ما إذا كانت i وj وk موجودة على المكدس أم أنها عالمية

وينطبق هذا بشكل خاص على العالم الصغير المضمن، حيث لم يتم إعداد المعالجات للتعامل مع لغة C.لذا فإن إجابتي ستكون أن C وC++ سيئان تمامًا مثل بعضهما البعض، إلا إذا قمت دائمًا بفحص مخرجات asm، وفي هذه الحالة يكونان بنفس جودة بعضهما البعض.

هوغو

لقد سمعت أن بعض الأشخاص يفضلون لغة C للعمل المضمن لأنها أبسط وبالتالي أسهل في التنبؤ بالكود الفعلي الذي سيتم إنشاؤه.

أنا شخصياً أعتقد أن كتابة C-style C++ (باستخدام قوالب لسلامة النوع) ستمنحك الكثير من المزايا ولا أرى أي سبب حقيقي لعدم القيام بذلك.

لا أرى أي سبب لاستخدام C بدلاً من C++.كل ما يمكنك القيام به في لغة C، يمكنك القيام به أيضًا في لغة C++.إذا كنت تريد تجنب النفقات العامة لـ VMT، فلا تستخدم الأساليب الافتراضية وتعدد الأشكال.

ومع ذلك، يمكن لـ C++ توفير بعض التعابير المفيدة جدًا دون أي تكاليف إضافية.واحدة من المفضلة لدي هي RAII.الفصول الدراسية ليست باهظة الثمن بالضرورة من حيث الذاكرة أو الأداء ...

لقد كتبت بعض التعليمات البرمجية لمنصة ARM7 المضمنة على IAR Workbench.أوصي بشدة بالاعتماد على القوالب للقيام بتحسين وقت الترجمة والتنبؤ بالمسار.تجنب الصب الديناميكي مثل الطاعون.استخدم السمات/السياسات لصالحك، كما هو منصوص عليه في كتاب أندريه ألكسندريسكو، التصميم الحديث بلغة C++.

أعلم أنه قد يكون من الصعب التعلم، ولكنني متأكد أيضًا من أن منتجك سيستفيد من هذا النهج.

السبب الجيد وأحيانًا السبب الوحيد هو عدم وجود مترجم C++ للنظام المضمن المحدد.هذا هو الحال على سبيل المثال ل الموافقة المسبقة عن علم رقاقة وحدات التحكم الدقيقة.من السهل جدًا الكتابة لها ولديها مترجم C مجاني (في الواقع، نسخة طفيفة من C) ولكن لا يوجد مترجم C++ في الأفق.

بالنسبة لنظام مقيد بـ 4K من ذاكرة الوصول العشوائي، سأستخدم C، وليس C++، فقط حتى تتمكن من التأكد من رؤية كل ما يحدث.الشيء في C++ هو أنه من السهل جدًا استخدام موارد أكثر بكثير (وحدة المعالجة المركزية والذاكرة) أكثر مما يبدو عند إلقاء نظرة خاطفة على الكود.(أوه، سأقوم بإنشاء BlerfObject آخر للقيام بذلك... عفوًا!خارج الذاكرة!)

يمكنك القيام بذلك بلغة C++، كما ذكرنا سابقًا (بدون RTTI، ولا vtables، وما إلى ذلك)، ولكنك ستقضي وقتًا طويلاً في التأكد من أن استخدامك لـ C++ لن يبتعد عنك كما تفعل مع ما يعادله في لغة C. .

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

لمحاربة هذا الاتجاه، أفضّل لغة C على لغة C++، لأنها تجبرك على التفكير في التعليمات البرمجية الخاصة بك، وكيفية تفاعلها مع الأجهزة بشكل أوثق - قريبة بلا هوادة.

من خلال خبرتي الطويلة، أعتقد أن لغة C تجبرك على التوصل إلى حلول أفضل للمشكلات، جزئيًا، عن طريق الابتعاد عن طريقك وعدم إجبارك على إضاعة الكثير من الوقت في تلبية قيد يعتقد بعض مؤلفي المترجمين أنها فكرة جيدة أو معرفة ما يجري "تحت الأغطية".

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

ربما أكون مناسبًا لقالب المبرمج جيدًا - أحب التحكم.من وجهة نظري، هذا ليس عيبًا في شخصية المبرمج.السيطرة هي ما نتقاضاه مقابل القيام به.وبشكل أكثر تحديدًا، السيطرة على نحو لا تشوبه شائبة.تمنحك لغة C تحكمًا أكبر بكثير من لغة C++.

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

لاحظ أن الأمر لا يتعلق باللغة أيضًا على أي حال، نظرًا لأن المكتبة مهمة أيضًا.غالبًا ما يكون لمكتبات C حجم أدنى أصغر قليلًا، لكن يمكنني أن أتخيل أن مكتبة C++ التي تستهدف التطوير المضمن قد تم تقليصها، لذا تأكد من اختبارها.

يقول البعض أن مترجمي لغة C يمكنهم إنشاء تعليمات برمجية أكثر كفاءة لأنهم لا يحتاجون إلى دعم ميزات C++ المتقدمة وبالتالي يمكن أن يكونوا أكثر عدوانية في تحسيناتهم.

بالطبع، في هذه الحالة قد ترغب في اختبار المترجمين المحددين.

تفوز لغة C بقابلية النقل - لأنها أقل غموضًا في مواصفات اللغة؛وبالتالي توفر قابلية نقل ومرونة أفضل بكثير عبر المترجمين المختلفين وما إلى ذلك (صداع أقل).

إذا كنت لا تنوي الاستفادة من ميزات C++ لتلبية احتياجاتك، فانتقل إلى C.

هل ترى أي سبب التمسك C89 عند وضع لفترة محدودة جدا الأجهزة (4kb من ذاكرة الوصول العشوائي)?

شخصيا عندما يتعلق الأمر جزءا لا يتجزأ من التطبيقات (عندما أقول جزءا لا يتجزأ من, أنا لا أقصد جفل, اي فون, الخ..المتضخمة جزءا لا يتجزأ من الأجهزة اليوم).أعني مورد محدود من الأجهزة.أنا أفضل ج ، على الرغم من أنني عملت مع C++ قليلا جدا وكذلك.

على سبيل المثال الجهاز الذي تتحدث عنه وقد 4kb من ذاكرة الوصول العشوائي ، حسنا فقط لهذا السبب أنا لن تنظر في C++.بالتأكيد, كنت قد تكون قادرة على تصميم شيء صغير باستخدام C++ و الحد من الاستخدام الخاص بك في التطبيق الخاص بك مثل الوظائف الأخرى واقترح ولكن C++ "أن" يحتمل أن تكون في نهاية المطاف تعقيد/النفخ التطبيق الخاص بك تحت الأغطية.

أنت ذاهب إلى رابط ثابت?قد ترغب في مقارنة ثابتة دمية التطبيق باستخدام c++ vs c.التي قد تقودك إلى النظر في ج بدلا من ذلك.من ناحية أخرى إذا كنت قادرا على بناء تطبيق C++ ضمن متطلبات الذاكرة ، لأنها تذهب.

IMHO ، في التطبيقات المضمنة أود أن أعرف كل ما يجري.من استخدام الذاكرة/موارد النظام ، ومدى لماذا ؟ متى مجانا ؟

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

عادةً ما يتم تحديد خياري من خلال مكتبة C التي نقرر استخدامها، والتي يتم تحديدها بناءً على ما يحتاج الجهاز إلى القيام به.يعني 9/10 مرات..وينتهي به الأمر ليكون uclibc أو newlib وC.النواة التي نستخدمها لها تأثير كبير على هذا أيضًا، أو إذا كنا نكتب النواة الخاصة بنا.

إنه أيضًا اختيار للأرضية المشتركة.معظم مبرمجي لغة C الجيدين ليس لديهم مشكلة في استخدام لغة C++ (على الرغم من أن الكثير منهم يشكون طوال الوقت الذي يستخدمونه فيه).لكنني لم أجد أن العكس هو الصحيح (في تجربتي).

في المشروع الذي نعمل عليه (الذي يتضمن نواة أساسية)، تتم معظم الأشياء في لغة C، ومع ذلك تم تنفيذ مجموعة صغيرة من الشبكة في لغة C++، لأنه كان أسهل وأقل مشكلة في تنفيذ الشبكات باستخدام لغة C++.

والنتيجة النهائية هي أن الجهاز إما أن يعمل ويجتاز اختبارات القبول أو لا.إذا كان بإمكانك تنفيذ قيود foo في xx stack وyy heap باستخدام اللغة z، فافعل ذلك، واستخدم أي شيء يجعلك أكثر إنتاجية.

تفضيلي الشخصي هو C لأنه:

  • أعرف ما يفعله كل سطر من التعليمات البرمجية (والتكاليف)
  • لا أعرف C++ جيدًا بما يكفي لمعرفة ما يفعله كل سطر من التعليمات البرمجية (والتكاليف)

نعم، أنا مرتاح مع لغة C++، لكنني لا أعرفها كما أعرف لغة C القياسية.

الآن إذا كان بإمكانك قول عكس ذلك، حسنًا، استخدم ما تعرفه :) إذا نجح، واجتاز الاختبارات، وما إلى ذلك ..ما هي المشكلة؟

كم ROM / فلاش لديك؟

4 كيلو بايت من ذاكرة الوصول العشوائي لا يزال يعني أن هناك مئات الكيلوبايت من فلاش لتخزين الكود الفعلي والبيانات الثابتة.ذاكرة الوصول العشوائي (RAM) بهذا الحجم مخصصة للمتغيرات فقط، وإذا كنت حريصًا مع تلك المتغيرات، فيمكنك احتواء برنامج كبير جدًا من حيث سطور التعليمات البرمجية في الذاكرة.

ومع ذلك، تميل لغة C++ إلى جعل وضع التعليمات البرمجية والبيانات في FLASH أكثر صعوبة، وذلك بسبب قواعد إنشاء الكائنات في وقت التشغيل.في لغة C، يمكن بسهولة وضع البنية الثابتة في ذاكرة FLASH والوصول إليها ككائن ثابت للأجهزة.في لغة C++، يتطلب الكائن الثابت من المترجم تقييم المُنشئ في وقت الترجمة، وهو ما أعتقد أنه لا يزال أبعد مما يمكن أن يفعله مترجم C++ (من الناحية النظرية، يمكنك القيام بذلك، ولكن من الصعب جدًا القيام به عمليًا) .

لذلك في بيئة "ذاكرة الوصول العشوائي الصغيرة" و"الفلاش الكبير" سأختار لغة C في أي يوم.لاحظ أن الخيار المتوسط ​​الجيد هو C99 الذي يحتوي على معظم ميزات C++ الرائعة للكود غير المستند إلى فئة.

بشكل عام لا.C++ هي مجموعة فائقة من C.سيكون هذا صحيحًا بشكل خاص بالنسبة للمشاريع الجديدة.

أنت على الطريق الصحيح في تجنب بنيات C++ التي يمكن أن تكون باهظة الثمن من حيث وقت وحدة المعالجة المركزية وبصمة الذاكرة.

لاحظ أن بعض الأشياء مثل تعدد الأشكال يمكن أن تكون ذات قيمة كبيرة - فهي في الأساس مؤشرات وظيفية.إذا وجدت أنك بحاجة إليها، استخدمها بحكمة.

كما أن معالجة الاستثناءات الجيدة (المصممة جيدًا) يمكن أن تجعل تطبيقك المضمن أكثر موثوقية من التطبيق الذي يتعامل مع الأشياء التي تحتوي على رموز خطأ تقليدية.

السبب الوحيد لتفضيل C IMHO هو أن مترجم C++ لنظامك الأساسي ليس في حالة جيدة (عربات التي تجرها الدواب، تحسين ضعيف، إلخ).

الكتاب C++ لمبرمجي الألعاب يحتوي على معلومات تتعلق بموعد زيادة حجم التعليمات البرمجية بناءً على ميزات C++.

لديك مضمنة في C99.ربما تحب الأطباء، لكن الحصول على الأطباء بشكل صحيح يمكن أن يكون فوضويًا.إذا كان السبب الوحيد المتبقي لعدم استخدام لغة C هو مساحات الأسماء، فسألتزم حقًا بـ C89.هذا لأنك قد ترغب في نقله إلى نظام أساسي مضمن مختلف قليلاً.يمكنك لاحقًا البدء في الكتابة بلغة C++ بنفس الرمز.ولكن احذر مما يلي، حيث أن C++ ليست مجموعة شاملة من C.أعلم أنك قلت أن لديك مترجم C89، ولكن هل تقارن C++ مع C99 على أي حال، حيث أن العنصر الأول على سبيل المثال ينطبق على أي لغة C منذ K&R.

الحجم "أ" > 1 في C، وليس في C++.في C لديك صفائف VLA متغيرة الطول.مثال: وظيفة (كثافة أنا) {كثافة العمليات [i].في C لديك أعضاء صفيف متغير VAM.مثال: البنية {int ب؛int م[]؛}.

أريد فقط أن أقول أنه لا يوجد نظام بموارد "غير محدودة".كل شيء في هذا العالم محدود ويجب على كل تطبيق أن يأخذ بعين الاعتبار استخدام الموارد بغض النظر عما إذا كان ASM أو C أو JAVA أو JavaScript.الدمى التي تخصص عددًا قليلًا من ميغابايت "للتأكد فقط" تجعل أجهزة iPhone 7 وPixel والأجهزة الأخرى ثقيلة للغاية.بغض النظر عما إذا كان لديك 4 كيلو بايت أو 40 جيجا بايت.

ولكن من ناحية أخرى، فإن معارضة إهدار الموارد هو الوقت الذي يستغرقه الحفاظ على تلك الموارد.إذا استغرق الأمر أسبوعًا إضافيًا لكتابة شيء بسيط في لغة C لحفظ بعض العلامات وبضع بايتات بدلاً من استخدام C++ الذي تم تنفيذه واختباره وتوزيعه بالفعل.لماذا تهتم؟إنه مثل شراء محور USB.نعم يمكنك أن تفعل ذلك بنفسك ولكن هل سيكون أفضل؟أكثر موثوقية؟أرخص إذا كنت تحسب وقتك؟

مجرد فكرة جانبية - حتى الطاقة من منفذ البيع الخاص بك ليست غير محدودة.حاول البحث عن مصدره وسترى في الغالب أنه ناتج عن حرق شيء ما.قانون الطاقة والمادة لا يزال ساري المفعول:فلا تظهر أو تختفي أي مادة أو طاقة بل تتحول.

بالنسبة لمشكلة تخصيص الذاكرة، يمكنني أن أوصي باستخدام Quantum Platform ونهج آلة الحالة الخاص بها، حيث أنه يخصص كل ما تحتاجه في وقت التهيئة.كما أنه يساعد على تخفيف مشاكل الخلاف.

يعمل هذا المنتج على كل من C وC++.

ذلك يعتمد على المترجم.

ليس كل المترجمين المضمنين ينفذون كل لغة C++، وحتى إذا فعلوا ذلك، فقد لا يكونون جيدين في تجنب تضخم التعليمات البرمجية (وهو ما يمثل دائمًا خطرًا مع القوالب).اختبره باستخدام عدد قليل من البرامج الصغيرة، لمعرفة ما إذا كنت تواجه أي مشاكل.

ولكن نظرا ل جيد مترجم، لا، ليس هناك سبب لعدم استخدام C++.

لقد عثرت للتو على مثال لكيفية استخدام ISO C++ للتطوير المضمن، والذي قد يكون مثيرًا للاهتمام بالنسبة لشخص يتخذ القرار عند استخدام C++ أو C.

تم تقديمه بواسطة بيارن ستروستروب في صفحته الرئيسية:

لإلقاء نظرة على كيفية استخدام ISO C++ لبرمجة الأنظمة المضمنة الجادة، راجع معايير ترميز C++ للمركبات الجوية JSF.

مشاركة إجابة مختلفة لجانب مختلف من السؤال:

"مالوك"

بعض الردود السابقة تتحدث قليلا عن هذا.لماذا تعتقد أصلاً أن هذه المكالمة موجودة؟بالنسبة لمنصة صغيرة حقًا، يميل موقع malloc إلى أن يكون غير متاح، أو اختياريًا بالتأكيد.إن تنفيذ تخصيص الذاكرة الديناميكية يميل إلى أن يكون مفيدًا عندما يكون لديك نظام RTOS في الجزء السفلي من نظامك - ولكن حتى ذلك الحين، فهو أمر خطير تمامًا.

يمكنك الوصول إلى مسافة بعيدة جدًا بدونها.مجرد التفكير في جميع برامج FORTRAN القديمة التي لم يكن لديها حتى مكدس مناسب للمتغيرات المحلية ...

هناك عدد من الشركات المصنعة المختلفة لوحدات التحكم في جميع أنحاء العالم، وعندما تلقي نظرة على تصميماتها ومجموعات التعليمات التي يجب استخدامها للتكوين، فقد ينتهي بك الأمر إلى الكثير من المشاكل.العيب الرئيسي للغة التجميع هو أنها تعتمد على الآلة/الهندسة المعمارية.إنه أمر ضخم حقًا أن نطلب من المطور أن يحفظ جميع التعليمات الموضحة هناك لإنجاز البرمجة لوحدات تحكم مختلفة.ولهذا السبب أصبحت لغة C أكثر شعبية في التطوير المضمن لأن لغة C عالية المستوى بما يكفي لاستخلاص الخوارزميات وهياكل البيانات من التفاصيل المعتمدة على الأجهزة، مما يجعل الكود المصدري قابلاً للحمل عبر مجموعة واسعة من الأجهزة المستهدفة، ولغة مستقلة عن الهندسة المعمارية وسهل جدًا تحويل والحفاظ على التعليمات البرمجية.لكننا نرى بعض اللغات عالية المستوى (موجهة للكائنات) مثل C وC++ وPython وJava وما إلى ذلك.تتطور بما يكفي لجعلها تحت رادار تطوير النظام المدمج.

على مثل هذا النظام المحدود.فقط اذهب للمجمع.يمنحك السيطرة الكاملة على كل جانب، ولا يعطي أي تكاليف إضافية.

ربما يكون أسرع كثيرًا أيضًا نظرًا لأن الكثير من المترجمات المضمنة ليست أفضل أدوات التحسين (خاصة إذا قارناها بأحدث المترجمات مثل تلك الموجودة لدينا لسطح المكتب (إنتل، والاستديو المرئي، وما إلى ذلك))

"نعم نعم...ولكن ج قابلة لإعادة الاستخدام و...".في مثل هذا النظام المحدود، من المحتمل أنك لن تعيد استخدام الكثير من هذا الرمز على نظام مختلف على أي حال.على نفس النظام، يكون المجمّع قابلاً لإعادة الاستخدام.

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