الطبقة باستخدام العالمية extern const المتغير الذي يتم تعريفه مع الداخلية الربط

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

سؤال

لدي هذا الموقف:

// Test.h
extern const int param;
class Test
{
private:
    int i;
public:
    int foo();
};

و

// Test.cpp
#include "Test.h"
int Test::foo() { return param*10; }

و

// core.h
#include "Test.h"
const int param = 1; // should have internal linkage later in core.cpp
int do_stuff ();

و

// core.cpp
#include "core.h"
int do_stuff () { Test obj; return obj.foo(); }
int main() { return do_stuff(); }

ومع ذلك لا يوجد خطأ linker.كيف ترى رابط Test.cpp على const int param وهو طريق الأساسية.ساعة محددة في core.cpp بعد أن الداخلية الربط (الافتراضي const التعاريف)?

عندما كنت كتابة الأساسية.ح مثل هذا (التغيير سطرين):

// core.h
const int param = 1;
#include "Test.h"
int do_stuff ();

هناك يأتي خطأ linker عن المفقودين param.ثم عندما تغييره مثل هذا:

// core.h
extern const int param = 1;
#include "Test.h"
int do_stuff ();

كل ذلك يعمل مرة أخرى.

فكرت أنه ربما الأصلي في الوضع التلقائي inlining من فئة الاختبار داخل core.cpp بحيث Test.cpp هي لا موجودة و كل رمز هو في core.cpp حتى أن كل شيء يعمل.ولكن لماذا يجب أن تكون ثم تعتمد من تغيير اثنين من الخطوط الأساسية.h ؟

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

المحلول

توليكم عن الداخلية الربط عن const التعاريف ليس صحيحا دائما.ترى ستاندارت القسم 3.5 Program linkage, p.3 (أقتبس N3690):

اسم وجود مساحة اسم النطاق (3.3.6) وقد الداخلي الربط إذا كان اسم

  • متغير, وظيفة أو وظيفة القالب الذي أعلن صراحة ثابتة ؛ أو ،

  • غير المتقلب المتغير الذي أعلن صراحة const أو constexpr ولا أعلن صراحة extern ولا أعلن سابقا أن يكون الخارجية الربط;أو

  • بيانات عضو مجهول الاتحاد.

حتى بالنسبة للحالة الأولى param وقد الخارجي الربط و كل شيء على ما يرام.

عن الحالة الثانية ، هناك داخلية مرتبطة param في core.cpp ولكن هناك آخر أعلن فقط param بعد أن الخارجية الربط ولكن لا تعريف.

في الحالة الثالثة ، هناك واحد param مرة أخرى.

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