הייתם צריכים לראות מה הקומפיילר עושה
בשביל לקלוט באג שנובע מכלל בסיסי של עובדה עם נקודה צפה שמלמדים בכל קורס מבוא ל-C?
לא רציתי לכתוב זאת קודם, אבל היות והשרשור הזה ממשיך, אציין זאת:
אני מריח אצלכם הרגלי עבודה רעים, והם אלה שמביאים למצבים מוזרים.
למשל, הצורך בעריכה מסיבית של הערות בנפרד לעריכת הקוד אליהן הן שייכות מראה על הרגלי תיעוד רעים.
אם לא שומרים על הערה תואמת לקוד בזמן אמת, היא בקלות הופכת לא רלוונטית, ואז לא רק שמבוזבז בסוף יותר זמן לתקן אותה כי צריך להבין מחדש מה קוד עושה, אלא גם עלולים להבין לא נכון וליצור הערה שנראית טוב אבל מטעה ומפריע בדיבג.
בנוסף, אם משתמשים בהערות בלוק סטייל C, לא כ"כ קל בטעות לפגוע בקוד. זה חשש מעט מוזר.
הרבה יותר מסוכן השימוש ב-define, בגלל אופי ה-copy / paste שלו.
למשל, הקוד הזה יתקמפל תקין, אבל לא ייתן את התוצאה הרצויה בגלל תו אחד קטן:
קוד:
#include <stdio.h>
2
3 #define BUG 10;
4
5 int main(int argc, char **argv) {
6 int a = BUG;
7 int i;
8
9 for (i = 0; i < 10; i++) a = BUG + i + 1;
10
11 printf("a = %d\n", a);
12
13 return 0;
14 }
האם אתה מזהה את התו?
כמו כן, define בקלות יכול להחביא בעיה מהסוג שהצגת בהודעתך שנובעת מכללי המרה אוטומטיים של C.
מה שמביא אותי לעוד נקודה:
אם כבר הולכים להכניס define הרי שלעשות את זה אחרי שהנתון המוחלף כבר נמצא בשימוש רחב הוא מתכון לטעויות.
טעויות שלא בהכרח יחשפו ע"י השוואת בינארים.
אני אתן לך דוגמה:
קוד:
/*** Code using magic numbers, no defines ***/
int num_of_fireman = 7;
int count = 0;
while (count < 7) {
fireman_get_on_firetruck(count);
count++;
}
/*** Lets use define to make the code more readable ***/
#define NUM_OF_FIREMAN_ON_DUTY 7
int num_of_fireman = NUM_OF_FIREMAN_ON_DUTY;
int count = 0;
while (count < NUM_OF_FIREMAN_ON_DUTY) {
fireman_get_on_frietruck(count);
count++;
}
/*** but what the code REALLY MEANS ***/
#define NUM_OF_FIREMAN_ON_DUTY 7
#define FIRE_TRUCK_CREW_SIZE 7
int num_of_fireman = NUM_OF_FIREMAN_ON_DUTY;
int count = 0;
while (count < FIRE_TRUCK_CREW_SIZE) {
fireman_get_on_frietruck(count);
count++;
}
עכשיו, הבינארי יצא זהה עם ובלי ה-define, אבל כשמחר יחליטו לשנות את מספר הכבאים בתחנה, בטעות ובלי לשים לב ישנו גם את מספר הכבאים שנכנסים בתוך משאית כיבוי, מה שלא נכון לחלוטין!
זו דוגמה מאוד מופשטת, אבל שוב - כשיש לך אותו נתון בהרבה מקומות בקוד ואתה מחליף אותו בדיעבד ב-define או קבוע, צריך להיות מאוד מאוד זהיר לוודא שאתה באמת מחליף את אותו הנתון בדיוק ולא נתון שבמקרה כרגע זהה.
שום השוואה בינארית לא תציל אותך מזה, לכן עדיף לקבוע קבועים מראש, או לפחות מוקדם ככל האפשר בתהליך כתיבת הקוד כשרואים שהנתון חוזר על עצמו.
אצלנו אגב, יש כלל זהב - בלי magic numbers בכלל!
בכל אופן, אין לי בעיה עם זה שאתם משווים בינארים או שומרים אותם ב-CSV, אבל ככל שהדיון נמשך אני רואה יותר ויותר למה זה לא מנהג נפוץ בתעשיה, ושאולי הבעיה היא פחות טבע התכנות למיקרו בקרים ויותר הרגלי ונהלי תכנות שכדאי לשקול לשנות ולתרגל כדי לחסוך זמן ובאגים פוטנציאליים.