סלאט ב INCLUDEים צריך הסבר - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

סלאט ב INCLUDEים צריך הסבר


MasterDK

Recommended Posts

יש קוד כזה:


#include <stdio.h>

int main(){
return 0;
}

האם התוכן של STDIO יכנס לקובץ אחרי הקומפילציה?

ההיגיון אומר שכן, אלה עם הקומפיילר יודע לעשות אופטימיזציה ו"לגזור" קוד שלא השתמשתי בו.

אשמח לתשובה.

תודה רבה מראש.

קישור לתוכן
שתף באתרים אחרים

קודם כל, אינקלוד זו פקודה "עיוורת". היא פשוט מדביקה את התוכן של הקובץ stdio.h. כל פונקציה שמוגדרת וממומשת שם תתקמפל כאילו היא נכתבה בקובץ שבו שמת את פקודת האינקלוד.

הקומפיילר לא יכול להחליט למחוק פונקציות שלא השתמשת בהן, כיוון שייתכן שאיזשהו קובץ אחר צריך את הפונקציות האלו (הקומפיילר דואג לקמפל כל קובץ C בנפרד לקובץ obj, והלינקר דואג לחבר אותם יחד לקובץ אחד - exe, lib או dll).

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

קישור לתוכן
שתף באתרים אחרים

קודם כל, אינקלוד זו פקודה "עיוורת". היא פשוט מדביקה את התוכן של הקובץ stdio.h. כל פונקציה שמוגדרת וממומשת שם תתקמפל כאילו היא נכתבה בקובץ שבו שמת את פקודת האינקלוד.

הקומפיילר לא יכול להחליט למחוק פונקציות שלא השתמשת בהן, כיוון שייתכן שאיזשהו קובץ אחר צריך את הפונקציות האלו (הקומפיילר דואג לקמפל כל קובץ C בנפרד לקובץ obj, והלינקר דואג לחבר אותם יחד לקובץ אחד - exe, lib או dll).

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

בדיוק מה שחשבתי והייתי בטוח בזה ב 100% עד שלא ניסיתי את הדבר הבא:

להלן פלט של רצף פקודות מסויים:


[ skwo@Moonlight dev ] cat foo.c
#include <stdio.h>

int main(){
return 0;
}
[ skwo@Moonlight dev ] gcc foo.c
[ skwo@Moonlight dev ] ls -l
total 16
-rwxr-xr-x 1 skwo skwo 4575 2009-06-02 19:39 a.out
-rw-r--r-- 1 skwo skwo 45 2009-06-02 19:39 foo.c
-rw-r--r-- 1 skwo skwo 92 2009-06-02 18:19 foo.c~
[ skwo@Moonlight dev ]

נא לשים לב לגודל של ה executable

להלן רצף נוסף:


[ skwo@Moonlight dev ] cat foo.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(){
return 0;
}
[ skwo@Moonlight dev ] gcc foo.c
[ skwo@Moonlight dev ] ls -l
total 16
-rwxr-xr-x 1 skwo skwo 4575 2009-06-02 19:41 a.out
-rw-r--r-- 1 skwo skwo 83 2009-06-02 19:41 foo.c
-rw-r--r-- 1 skwo skwo 45 2009-06-02 19:39 foo.c~
[ skwo@Moonlight dev ]

לא מסתדר בראש נכון? הרי גם STDLIB וגם TIME הם קבצים לא קטנים שמכילים הרבה PROTOTYPES, אם כן למה זה לא מגדיל את הגודל של ה executable?

לפי הניסוי הזה אני יכול פשוט ליצור קובץ all.h שיכילים את כל ה HEADERS ולעשות לו INCLUDE בכל מקום שאני צריך אם הקומפיילר יודע לטפל בקוד "לא נחוץ".

אשמח להסבר.

שוב תודה רבה מראש :)

קישור לתוכן
שתף באתרים אחרים

prototypes לא משנים את הגודל של הקובץ המקומפל. הם בסך הגדרות שהקומפיילר משתמש בהן. ההגדרות האלה לא נכנסות לקובץ המקומפל.

:o תודה רבה לא ידעתי את זה!

קישור לתוכן
שתף באתרים אחרים

קודם כל, אני שמח לראות שיש אנשים שמתעניינים ב-C linkage model. זה נושא חשוב עם השלכות מעשיות, ולכן ואנחנו שואלים על זה בראיונות עבודה. הרבה אנשים נופלים והרבה אנשים מגמגמים. ישר כוח.

אני ממליץ בחום שתלמד איך תהליך הלינקוג' עובד, מה החלק של הקומפיילר, מה החלק של הלינקר.

הנה כמה מונחים לחפש:

object file

module

static library

dynamic library

symbol table

external symbol

undefined symbol

והנה לינק שבמבט חטוף נראה לא רע: http://www.tenouk.com/ModuleW.html

אחרי שתבין את הבסיס, תוכל בקלות יותר להבין מה אומר static ב-C, למה אסור להגדיר משתנים ב-#include אלא רק להצהיר עליהם, מה זה C++ name mangling ולמה הוא קיים, ועוד הרבה דברים אחרים, כולל השאלה ששאלת למעלה.

אם לתת הסבר מעט יותר מפורט (אבל עדיין פשטני), שאותו תוכל להבין אחרי שתלמד קצת:

1) כאשר אתה עושה #include לקובץ, הקומפיילר (למעשה preprocessor) פשוט מכניס את תוכנו לתוך הקובץ שאותו הוא מקמפל.

2) קבצי H מכילים prototype-ים בד"כ. למעשה אלה external symbols, וזה אומר לקומפיילר שמותר לו (אבל הוא לא חייב!) לפנות ולהשתמש ב-symbol (פונקציה או משתנה) אשר יוגדר בכלל בקובץ אחר, וזה באחריות הלינקר לדאוג לחבר את ה-symbol הזה.

3) הקומפיילר מייצר רשימה של symbol-ים חיצוניים כאלה שבהם הוא השתמש עבור הקובץ שאותו קימפלת.

4) הלינקר מקבל את הקוד שיצר הקומפיילר, את רשימת הסימבולים הקיימים והחיצוניים, וכן את כל הספריות והסימבולים שהם כוללים.

5) עכשיו ללינקר יש את כל המידע! הלינקר עובר על כל הסימבולים הנחוצים ובתהליך מסויים מכניס את כולם לקובץ EXE.

6) בתלות בכל מני תנאים מסויימים, הלינקר יכול להכניס רק את הסימבולים שבהם השתמשת בקוד שלך! (בד"כ חייבים קצת יותר, אבל לא בהכרח את כל מה שמוגדר בקובץ H).

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...