16-01-2009, 11:43
|
|
|
חבר מתאריך: 03.01.09
הודעות: 239
|
|
אל תעלב אבל קודם כל הבעיה היא שאתה לא מבין מה זה LINKAGE ,מה המטרה של PROTOTYPE -ים ואיך עובדת שפת C מה המטרה שלה ולמה היא נראית איך שהי נראית .אי אפשר ברצינות לדבר על שינויים שאתה רוצה לעשות במשהו שאתה בכלל לא מבין למה הוא נראה איך שהוא נראה .
קודם תבין למה המצב הקיים הוא כפי שהוא ,ואחרי זה תוכל לנסות לחשוב על שינויים שצריך לעשות .אין כזה הרבה שפות מוצלחות בעולם ויש לזה סיבה .זה לא פשוט כמו שאתה חושב .לבוא משומקום ולהגיד " צריך לשנות " "למה לא עשו ככה " בלי להכיר את הדברים האלה אפילו קצת זה לא רציני ,אפילו קצת מביך .
אני לא אומר שאתה צריך להגיד לעצמך " כזה ראה וקדש " - אף פעם אל תפקפק במה שאחרים עשו ובטח K&R כאלה תותחים שהם המציאו שפה מושלמת והכל שם נכון ,אבל אני לא מומחה בינלאומי ל- C ונראה לי שזה לא יהיה מוגזם מאוד להגיד שאני מכיר ומבין C קצת יותר טוב ממך ,ואני קצת יותר נזהר כשאני אומר " למה לא עשו "
עכשיו תבין PRTOTYPE ים הם לא קוד שרץ .זה לא קוד שמתקמפל לקוד מכונה .בהנחה שמה שיש לך בקבצים שאתה עושה עליהם אינקלוד זה PROTOTYPES אז אין אפילו משמעות למילים שאמרת " לקמפל את האינקלודים "
בגלל זה אמרתי לך למעלה שקודם תגיד מה הבעיה ומה הפיצ'ר שחסר לך ב- C ,ורק אז אם אתה מבין את העסק אתה יכול להתחיל להגיד מה לשנות .
מה שאתה אומר זה כמו שאני אגיד שאני רוצה שיהיה ב - C פיצ'ר שאפשר להפריד בין הכרזות על משתנים לא רק עם פסיק אלא גם עם סימן שטרודל:
זה מאוד נחמד והכל ,אבל בכלל לא הסברתי מה הבעיה שאני מנסה לפתור !
עכשיו בוא נעשה שיעור קצת בשפת C
איך קוראים לפונקציה בשפת C ?
הדרך הבסיסית לקרוא לפונקציות ב- C ב -x86 היא מה שנקרא cdecl
בשיטה הזאת דוחפים את הפרמטרים למחסנית מימין לשמאל ( ככה שהראשון שמוציאים זה הכי שמאלי -הראשון ) קוראים לפונקציה ואז אחרי שהפונקציה חוזרת מי שקרא לה מנקה את הפרמטרים מהמחסנית .
דוגמה מוויקיפדיה-
For instance, the following C code function prototype and function call:
קוד:
int function_name(int, int, int);
int a, b, c, x;
...
x = function_name(a, b, c);
will produce the following x86 Assembly code (written in MASM syntax, with destination first):
קוד:
push c
push b
push a
call function_name
add esp, 12 ;Stack clearing
mov x, eax
The calling function cleans the stack after the function call returns.
אבל יש עוד עניינים לגבי structים FLOATING POINT וערכי החזרה . בדרך כלל ערך ההחזרה חוזר ב -EAX או ב EAX וב EDX אם הוא גדול יותר ,אבל אם הוא FLOATING POINT בדרך כלל מחזירים אותו ב-ST(0) / fp0 .אבל GCC לדוגמה מחזיר STRCUT ים תמיד בזיכרון ,גם אם כל מה שיש בו זה שני int16-ים .
לא פשוט בכל אופן
מה קשור PROTOTYPES?
אבל איך הקומפיילר יודע כשהוא רואה שורה כמו
[code]double ret = cosh(13);[code]
מה זה 13 ? האם צריך לדחוף בייט עם הערך 13 או WORD עם הערך 13 או DWORD עם הערך 13 ?
בעצם ,מה שהוא צריך לדעת זה שהוא צריך להמיר את 13 ממספר שלם ל-FP ולהעביר אותו במחסנית של ה-COPROCESSOR .אבל איך הוא יכול לדעת את זה?
בשביל זה יש לו PROTOTYPE .ה-PROTOTYPE הוא רק עזרה לקומפיילר שאומרת לו איך לקמפל קריאות לפונקציות. ה-PROTOTYPES בעצמם לא מתקמפלים לקוד מכונה .
ועכשיו בגדול
אין משמעות לקיום של PROTOTYPE בתלות בתנאי זמן ריצה .צריך את ה- PROTOTYPE בזמן הקימפול כדי שהקומפיילר ידע מה לעשות עם פרמטרים של פונקציות .
C היא שפה שאמורה להיות low-level ולכן לחלוטין לא מקובל שבזמן ריצה הקוד יחליט מה לעשות עם הפמטרים איך לדחוף אותם ,באיזה סדר ,לאיזה טיפוסים להמיר ,איפה מקבלים את ערך ההחזרה וכולי .
למה ?
משתי סיבות:
* לא צריך את זה
* בעצם לפעמים קצת צריך את זה ,אבל מאוד קשה לקבוע תקן לדבר הזה ( בעצם תקן לדרך תקשורות בין מודולי תוכנה שונים כדי להחליט על דרך העברת הפרמטרים ביניהם- תקן לתקן- meta-תקן ) .גם אם קצת צריך את זה ,ההשקעה לחלוטין בלתי משתלמת וגובלת בבלתי אפשרית (אם לא חוצה את הגבול הזה )
דברים כאלה הם החלטה של המימוש ויש כל מיני מימושים שמספקים את האפשרות הזו לדוגמה IDispatch של COM .
בקיצור - סתם רצית שיעשו משהו בלי סיבה ובלי להבין למה באמת הוא איך שהוא עכשיו .אני לא סתם מתנגד במקום למצוא פיתרון ,אלא שאני מבין מה צריך ומה לא צריך למה הדברים כפי שהם ולכן יש לי עין ביקורתית גם כלפי המצב הקיים אבל גם כלפי הצעות מוזרות להתעלל בו .
תכנון שפת תכנות זה לא עסק של " וואלה מתחזק לי משהו בוא נעשה "
נערך לאחרונה ע"י Incred2 בתאריך 16-01-2009 בשעה 11:47.
|