לדלג לתוכן

פתרון מהמקור לקובץ אובייקט

הפניה החיצונית ב־main.obj נשארת בלתי פתורה עד שה־linker מקבל קלט שמגדיר את הסמל המבוקש. העובדה שה־header נמצא בנתיב include אינה מספקת מימוש. לכן תיקון הכשל הראשון הוא הוספת האובייקט או הספרייה המתאימים לקישור, ולא הוספת include נוסף.

בכשל של long נוצרת פונקציה בעלת חתימה אחרת. מכיוון שה־header עדיין מצהיר על גרסת int, הלקוח מבקש סמל אחד והמימוש מספק אחר. אפשר לראות את שני השמות באמצעות dumpbin /symbols, ולהשתמש ב־undname כדי לקרוא שם מעוטר שמופיע בפלט.

dumpbin /symbols main.obj
dumpbin /symbols math.obj
undname "?combine@@YAHHH@Z"

השם המעוטר בדוגמה מתאים לכלים מסוימים ולחתימה המסוימת, ולכן יש להעתיק לניסוי את השם שמופיע בפלט שלכם. אין להקשיח אותו בקוד יישומי.

בכשל השלישי קיימות שתי הגדרות חיצוניות של אותה פונקציה. פתרון רגיל הוא להשאיר הגדרה אחת בקובץ מקור ולפרסם הצהרה ב־header. אם הפונקציה צריכה להיות מוגדרת ב־header, אפשר לבחור inline לפי כללי ODR, כאשר ההגדרות עומדות בדרישות הזהות של השפה. הוספת static לכל מקום משנה את הזהות לישות נפרדת בכל יחידה, ולכן אינה תיקון שקול לכל שימוש.

ההבדל בין שתי הגדרות המקרו מופיע כבר בפלט preprocessing. עם SCALE=1 הביטוי מחבר שלוש לעשר; עם SCALE=4 הוא מחבר שתים־עשרה לעשר. השינוי לא נוצר בטעינה ולא בזמן הריצה, אלא לפני ניתוח הביטוי והפקת קוד המכונה.

בדיקת פונקציה שאינה בשימוש צריכה לציין אם היא באותו קובץ אובייקט עם פונקציה שכן נדרשת, ואם הופעלו אפשרויות כמו /Gy ו־/OPT:REF. יחידת הבחירה הראשונה של ארכיון סטטי אינה בהכרח פונקציה בודדת. אפשרויות הפרדה ל־sections וסילוק קוד לא נדרש משפיעות על התוצאה.

הדוח התקין כולל גרסת toolset, ארכיטקטורת יעד ופקודות. תוצאה שנמדדה ב־debug עם קישור אינקרמנטלי אינה מתארת בהכרח תוצר release. החקירה מתחילה מהמכונה שבאמת נבנתה, ואז חוזרת אל ההחלטות שהפיקו אותה.