printf מוזר

nocgod

New member
printf מוזר

אני מנסה להדפיס באמצעות printf (הקומפיילר gcc סביבת העובדה eclipse מעל לינוקס)
printf(" >>> %d sent %d bytes to %d : \"%s\", left bytes to write: %d\n",
getpid(), (int)nbytes, folderHandle->id, msg, (strlen(msg) + 1 - nbytes));


בצורה מאוד מוזרה יש לי אזהרה על הפרמטר השישי...רק שהוא לא קיים...
./main.c:464:4: warning: format ‘%d’ expects argument of type ‘int’, but argument 6 has type ‘long unsigned int’ [-Wformat]


מישהו מכיר על באג כזה? שמע? אולי יש לי איזה טעות בפורמט שנתתי לו?
 
הקומפילר מתכוון לפרמטר השישי של printf

שזה: (strlen(msg) + 1 - nbytes)
הפורמט הוא הפרמטר הראשון.

אם תחליף את הפרמטר האחרון ל-%lu זה יפתר.
 

nocgod

New member
אבל אתה צודק...

זה סידר את הwarning המוזר הזה...למרות שזה הפרמטר החמישי ולא השישי...
 

BravoMan

Active member
זה לא באג זה פיצ'ר


אבל ברצינות, מקרו הבדיקה עבור פרמטרים של printf הוא באמת פיצ'ר נחמד מאוד.
שים לב, ש-strlen מחזיר size_t ואם תמצא את ההגדרה שלו (מה שלא לגמרי פשוט), תראה שהוא למעשה unsigned long.
כך שכל ביטוי האחרון הוא אכן אינו int.
 

nocgod

New member
הצדק עמך...

:)
מה שהטעה אותי היה שהוא כתב שהבעיה בפרמטר השישי, כאשר בפועל הוא החמישי...:)

תודה
 

BravoMan

Active member
התאמת זווית ראייה:

צריך לזכור ש-printf היא פונקציה רגילה לחלוטין, כמו כל פונקציה אחרת.
גם אתה יכול לכתוב כזו.

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

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

int str;

printf(str);


האם היית מצפה לאזהרה על ארגומנט 0?
 

nocgod

New member
אתה צודק

משום מה לא נתתי חשיבות לזה שיש את הformat לפני שאר הפרמטרים חחח... אני כבר עייף מכל העבודות המעיקות האלה אז מתחילות שטויות...
וזה בסדר אני יודע שגם הפורמט הוא פרמטר...אני אזכיר שאני מתרגל C ו ++C... זה מצחיק שאני גם מסביר את זה לסטודנטים, אבל לא שמתי לב לטעות המפגרת הזאת...
 
למעלה