الطبقة باستخدام العالمية extern const المتغير الذي يتم تعريفه مع الداخلية الربط
-
26-12-2019 - |
سؤال
لدي هذا الموقف:
// 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
مرة أخرى.