سؤال

أنا باستخدام وحدة تسجيل يمكن أن يكون الإبلاغ تمكين/تعطيل في وقت التشغيل.المكالمات عموما يذهب شيء من هذا القبيل:

WARN(
     "Danger Will Robinson! There are "
     + boost::lexical_cast<string>(minutes)
     + " minutes of oxygen left!"
);

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

bool WARNINGS_ENABLED = false;
inline void WARN(const string &message) {
    if (!WARNINGS_ENABLED) {
       return;
    }
    // ...
}

بالنظر إلى أن بناء سلسلة حجة له أي آثار جانبية ، مترجم تحسين ذلك ؟ هو مستوى معين من التحسين المطلوبة (-Ox في g++ بعض x)?

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

المحلول

إذا كنت تحتاج إلى أن تكون قادرة على اختيار تمكين وتعطيل التحذيرات في وقت التشغيل، ومترجم و<م> لا تكون قادرة على تحسين مهلة استدعاء.

وما تحتاجه هو لإعادة تسمية الخاص بك وظيفة إلى WARN2 وإضافة شيء الكلي مثل:

#define WARN(s) do {if (WARNINGS_ENABLED) WARN2(s);} while (false)

وهذا سيمنع تقييم الصورة في وقت التشغيل إلا إذا قمت بتمكين التحذيرات.

ووافعل حين الاشياء هي خدعة التي تسمح لاستخدامها في أي مكان في رمز (بيان عارية، بيان ضمن استعدت إذا كتلة، بيانا خلال unbraced إذا كتلة، استعدت وunbraced حين البيانات وهلم جرا) .

نصائح أخرى

يمكنك التحقق من ما خليجية/G++ هل باستخدام -S خيار.هذا سيتم إخراج قانون قبل أن يحصل في الواقع تجميعها – انظر دول مجلس التعاون الخليجي(1).

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

char WARNINGS_ENABLED = 0;

inline void WARN(const char* message) {
    if (!WARNINGS_ENABLED) {
        return;
    }
    puts(message);
}

int main() {
    WARN("foo");
    return 0;
}

تشغيل دول مجلس التعاون الخليجي -O3 -S الملف.ج والنظر في ملف الإخراج 'الملف.s'
سوف ترى أن دول مجلس التعاون الخليجي لا إزالة أي شيء!

هذا ليس ما طلبته ، ولكن من أجل إعطاء مترجم الفرصة لتحسين التي رمز بها ، سيكون لديك لجعل WARNINGS_ENABLED ثابت.البديل هو أن تجعل ثابت وليس تغيير القيمة في هذا الملف. ولكن:مما يجعل ثابت له الآثار الجانبية أن الرمز لا يحصل تصديرها.

static const char WARNINGS_ENABLED = 0;

inline void WARN(const char* message) {
  if (!WARNINGS_ENABLED) {
      return;
  }
  puts(message);
}

int main() {
    WARN("foo");
    return 0;
}

دول مجلس التعاون الخليجي تماما ثم ينظف رمز.

وكنت أعتقد أنه ليس لديها سوى فرصة لتحسين بها إذا كان يمكن إثبات أنه لا توجد آثار جانبية (والذي قد يكون من الصعب على المترجم أن تفعل لاستدعاء دالة مكلفة).

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

inline void warnFunc(some_boost_lambda &message_generator) {
  if (WARNINGS_ENABLED) {
    cerr << message_generator() << endl;
  }
}

#define WARN(msg) warnFunc(...insert boost magic here to turn msg into a lambda...)

لا، مترجم ينبغي <م> لا CONST تحسين رمز في أي حال ما لم WARNING_ENABLED العالمية والمعلنة.

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

وفيما يلي بعض كفاءة (الحد الأدنى (قريبة من الصفر مع فرع يتوقع CPU) النفقات العامة عند تعطيل وقت التشغيل) <وأ href = "http://github.com/vicaya/hypertable/tree/master/src/cc/Common/ Logger.h "يختلط =" نوفولو noreferrer "> وحدات الماكرو تسجيل التي تدعم كلا من وظيفة وأسلوب تيار تسجيل.

ولا يمكنك فقط تحديد كل شيء خارج باستخدام المعالج؟

void inline void LogWarning(const string &message) 
{
  //Warning
}

#ifdef WARNINGS_ENABLED
#define WARN(a) LogWarning(a)
#else
#define WARN(a)
#endif

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

#ifdef WARNINGS_ENABLED
// Extra setup for warning
#endif
//....
WARN(uses setup variables)

وأنها سوف تجمع كلا الاتجاهين.

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

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