خطأ:× قد يكون استخدامها غير مهيأ في هذه الوظيفة في ج
-
06-07-2019 - |
سؤال
أنا على الحصول على هذا الخطأ
error: Access.Core may be used uninitialized in this function
و هذا هو الكود:
static int FirstTime = 1;
MyStruct Access;
if (FirstTime) {
FirstTime = 0;
Access = Implementation();
DoSomething(Access);
}
if(Other_Variable) {
Access = Implementation2();
DoSomething(Access);
}
//The Other_Variable will be set to 1 and to 0 by other part of the code
قانون بلدي مثل هذا لأنني أريد أن الدعوة إلى تنفيذ وظيفة فقط في المرة الأولى.في كل مكالمة الوصول المتغير سوف يتم تحديثها لذلك لا تجعل الكثير من الإحساس جعله ثابت.
إذا كنت تجعل الوصول ثابت يعمل, ولكن أنا لا أحب جعلها ثابتة لأنه في كل مكالمة أخرى الوصول سوف يتم تحديث.أي طريقة لتجنب هذه المشكلة دون أن يجعل الخطة؟.
أيضا أي أفضل الخيارات لتنفيذ مرة واحدة فقط في وظيفة بدلا من استخدام متغير ثابت هي موضع ترحيب.
المحلول
جعل Access
مثل هذا (وإزالة FirstTime
و if
):
static MyStruct Access = Implementation(this_b);
السبب في أنك تحصل على هذا التحذير بسبب متغيرات ثابتة البقاء على قيد الحياة واحد استدعاء دالة.قيمتها يتم الاحتفاظ كافة المكالمات وظيفة (دون يتعلق موضوع هذه الوظيفة).لذلك ، FirstTime
سيتم التحكم في ما إذا كان يمكنك تهيئة Access
.في المرة الأولى التي تتصل وظيفة هذا الكود في تهيئة بشكل صحيح Access
متغير.ولكن مع كل زيادة استدعاء دالة ، FirstTime
هو صفر, و سوف لا تهيئة Access
بعد الآن ، وبالتالي سيتم استخدام متغير غير مهيأ أسفل المدونة.
تحرير: الان مع تحديث المعلومات تقول أن لديك اثنين Implementation
المهام.أول مرة كنت ترغب في استخدام واحدة, و كل مرة كنت ترغب في استخدام وظيفة أخرى.ماذا عن هذا ثم:
// static will be false/zero by default
static bool AlreadyCalled;
MyStruct Access;
if (!AlreadyCalled) {
Access = Implementation();
AlreadyCalled = true;
} else {
Access = Implementation2();
}
اعتمادا على الاستخدام الفعلي الحالة ، قد تكون هناك طرق أفضل للتعامل مع هذا ، على الرغم من.على سبيل المثال لماذا لا يتم تحديث حالة Access
, مثل هذا:
// let the default constructor initialize it
// to a plausible state
static MyStruct Access;
// use RAII to update the state of Access when this
// function returns.
MyUpdater updater(Access);
// now, do whatever the function does.
شيء مثل هذا MyUpdater
:
struct MyUpdater {
MyStruct &s;
MyUpdater(MyStruct &s):s(s) { }
~MyUpdater() {
s.ChangeState();
}
};
هذا النمط يسمى RAII
:يمكنك إقران بعض المعلومات المفيدة في العمل مع منشئ والمدمر محلي تخصيص الكائن.
نصائح أخرى
و @الجواب litb هي مثيرة للاهتمام. يتبع برنامج مكافئ. رمز يجمع ويعمل كما جاء في C ++، ولكن لا ترجمة في C.
#include <stdio.h>
static int newval(void) { return 3; }
void inc(void)
{
static int a = newval();
a++;
printf("%d\n", a);
}
int main(void)
{
int i;
for (i = 0; i < 10; i++)
inc();
return(0);
}
ودول مجلس التعاون الخليجي يقول:
وx.c: في وظيفة "المؤتمر الوطني العراقي": x.c: 7: خطأ: العنصر مهيئ ليست ثابتة
وز ++ سعيدة جدا معها.
وهذا هو الفرق بين C و C ++ لأنني لم أكن على علم (ولكن هذا لا يصلح في 300 حرفا لذلك لا يمكن أن تجعل من تعليق، بسهولة).
وEduardo طلب أحد الأسئلة في التعليقات: "لماذا C لا نسمح لهذا وC ++ تسمح بذلك؟". منذ كان الجواب أكثر من 300 حرفا ... م>
وكما قالlitb في التعليقات، في C يمكنك فقط استخدام الثوابت لالمهيآت المتغيرات ثابتة. هذا هو في جزء منه لأنه يتم تعيين القيم قبل الرئيسي () ويسمى، وتسمى أي الدالات المعرفة من قبل المستخدم قبل الرئيسي () ويسمى. C ++، على النقيض من ذلك، يسمح المتغيرات العالمية وثابتة ليتم تهيئتها من قبل الصانعين (المعرفة) قبل الرئيسي () ويسمى، لذلك ليس هناك سبب لعدم سماح وظائف أخرى المعرفة من قبل المستخدم ليتم استدعاؤها للغاية، وبالتالي فإن التهيئة معقول. مع C89، هل تقتصر في المهيآت يمكنك استخدامها مع المتغيرات التلقائي (المحلية)؛ في C99، يمكنك استخدام الى حد كبير أي تعبير تهيئة أي متغير محلي.
وصول ليست ثابتة، وبالتالي يتم إنشاء مثيل جديد في كل مرة يتم استدعاء الدالة. فقط في المرة الأولى القيام به من خلال كنت في الواقع تعيين أي قيمة له؛ يتم فقدان هذه القيمة في أقرب وقت إنهاء الدالة.
إذا كنت بحاجة إلى الوصول إلى تستمر عبر المكالمات إلى وظيفة، وجعلها ثابتة.
وAccess
ليس ثابت، وبالتالي فإنه يجب إنشاء في كل مكالمة.
والنظر في تبسيط قانون لشيء من هذا القبيل:
static MyStruct Access = Implementation(this_b);
وهذا يضمن أن وظيفة وسوف يطلق فقط في المرة الأولى التي يتم فيها تشغيل الطريقة وسوف أن Access
عقد بين قيمة المكالمات.