السلام عليكم ورحمة الله وبركاته،
قبل فترة لاحظت امر غريب عندما كنت اكتب برنامج سي. انظر للمصدر التالي:
#include <stdio.h>
int i;
int inc(){ return ++i;}
int main(){
i=0; printf("i,inc(): %d,%d\n", i, inc());
i=0; printf("inc(),i: %d,%d\n", inc(), i);
}
عندما تقوم بتصرفه بإستخدام gcc و تشغيله يأتي بالمخرجات التالية:
i,inc(): 1,1
inc(),i: 1,0
تمعن جيدا بترتيب مدخلات printf و ترتيب تنفيذها وقارن المخرجات بما تتوقعه. مذا تلاحظ؟
المخرجات ليست مثلما توقعت، اليس كذلك.
ففي السطر الأول من الخرجات، ترى ان القيمة الأولى 1 على الرغم من ان ‘i’ لم تمس (بحسب ترتيب مدخلات printf في اول سطر بـmain). أيضا، ترى في السطر الثاني ان القيمة الثانية بقيت صفراً بالرغم من سبق inc() إياها. اي ان في كلا سطري المخرجات تختلف قيمة ‘i’ عن القيمة التي نتوقعها.
لم اجهد نفسي في البحث عن الإجابة او تفسير لهذه الظاهرة بل انتهزت الفرصة كي اختبر مجتمع لينكس العربي، ولم يخيب ظني. فقد فسرها اخي مؤيد السعدي بأن مدخلات الوظائف (functions) تخزن في اكوام (stacks) وان المدخل الأخير يعاين قبل سابقه، وهذا بلا شك يفسر هذه الظاهرة وهو تفسير صحيح. الأن السؤال يطرح نفسه: هل هذه الطرقة في معاينة المدخلات (اي تخزينها في اكوام) معرفة قياسيا في c89 او c99 ام هي طريقة انتهجها مصمموا gcc وقد تختلف من مصرف لآخر.
بحث سريع اظهر الحقيقة المرعبة التي تهز ثقتك (بقياسية؟) اللغة ان التعاريف القياسية (c89 و c99) لا تحدد ترتيب معاينة مدخلات الوظائف!
مع ذلك ما زلت أحبها ♥ <- وهذه ايضاً