Μεταγλώττιση και σύνδεση πολλαπλών αρχείων κώδικα. Προγραμματισμός II 1

Σχετικά έγγραφα
(programming interfaceή/και application programming interface API).

Προεπεξεργαστής C. Προγραμματισμός Ι 1

make Προγραμματισμός II 1

Βιβλιοθήκες Αφηρημένοι τύποι δεδομένων. Προγραμματισμός II 1

Το λειτουργικό σύστημα. Προγραμματισμός II 1

Το λειτουργικό σύστημα. Προγραμματισμός II 1

Το λειτουργικό σύστημα. Προγραμματισμός II 1

Προγραμματισμός Ι (ΗΥ120)

CE121 Προγραµµατισµός 2. Εισαγωγή σε Makefiles. CE121 -

CE121 Προγραµµατισµός 2. Εισαγωγή σε Makefiles. CE121 -

Ανάπτυξη και Σχεδίαση Λογισμικού

Η γλώσσα προγραμματισμού C

Προγραμματισμός Ι. Πολλαπλά Αρχεία. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραμματισμός Ι (ΗΥ120)

ΕΙΣΑΓΩΓΗ ΣΤΟN ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

Λύβας Χρήστος Αρχική επιµέλεια Πιτροπάκης Νικόλαος και Υφαντόπουλος Νικόλαος

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (2)

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Ι (ΗΥ120)

Δομημένος Προγραμματισμός

4. Συντακτικό μιας γλώσσας είναι το σύνολο των κανόνων που ορίζει τις μορφές με τις οποίες μια λέξη είναι αποδεκτή.

ΑΦAΙΡΕΤΙΚΟΣ (ή ΑΦΗΡΗΜΕΝΟΣ) ΤΥΠΟΣ ΔΕΔΟΜΕΝΩΝ (ΑΤΔ) (Abstract Data Type-ADT) - σύνολο δεδομένων (data, objects) - σύνολο πράξεων στα δεδομένα

Διαδικασιακός Προγραμματισμός

Διαδικαστικός Προγραμματισμός

Ενότητες στην C Τεχνική Υλοποίησης Αφαιρετικών Τύπων Δεδομένων στην C

ΤΥΠΟΣ ΔΕΔΟΜΕΝΩΝ (ΑΤΔ) (Abstract Data Type-ADT)

Ανάπτυξη και Σχεδίαση Λογισμικού

Προεπεξεργαστής της C. C Preprocessor. Προγραμματισμός II 1

Δομημένος Προγραμματισμός

ΕΡΓΑΣΤΗΡΙΟ 6: Συναρτήσεις και Αναδρομή

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Εισαγωγή στον Προγραµµατισµό. Πανεπιστήµιο Θεσσαλίας Τµήµα Ηλεκτρολόγων Μηχανικών και Μηχανικών Η/Υ

Η γλώσσα προγραμματισμού C

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

Η-Υ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ. Εργαστήριο 1 Εισαγωγή στη C. Σοφία Μπαλτζή s.mpaltzi@di.uoa.gr

ΕΙΔΗ,ΤΕΧΝΙΚΕΣ ΚΑΙ ΠΕΡΙΒΑΛΛΟΝΤΑ ΠΡΟΓΡΑΜΜΑΤΙ- ΣΜΟΥ

Δομημένος Προγραμματισμός

Προηγμένοι Μικροεπεξεργαστές. Εργαστήριο 6 C & Assembly

Μνήμη Διευθύνσεις Δείκτες. Προγραμματισμός II 1

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

Προγραμματισμός ΙI (Θ)

Προγραμματισμός Ι. Συναρτήσεις. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

Μαλούτα Θεανώ Σελίδα 1

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II. Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact:

Εργαστήριο Λειτουργικών Συστημάτων 8o εξάμηνο, Ροή Υ, ΗΜΜΥ

Πληροφορική 2. Γλώσσες Προγραμματισμού

Διάλεξη 22η: Επιπλέον στοιχεία της C

Προγραμματισμός Ι (ΗΥ120)

Εισαγωγή στην Πληροφορική

Δομημένος Προγραμματισμός

Υλοποίηση ενός προγραμματιστικού κελύφους εργασίας

Η γλώσσα προγραμματισμού C

Διαδικασιακός Προγραμματισμός

ΕΙΣΑΓΩΓΗ ΣΤΟΥΣ ΑΛΓΟΡΙΘΜΟΥΣ ΚΑΙ ΣΤΟΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Προγραμματισμός Η/Υ (ΤΛ2007 )

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

ΕΡΓΑΣΤΗΡΙΟ 3: Προγραμματιστικά Περιβάλλοντα και το Πρώτο Πρόγραμμα C

Διαφορές single-processor αρχιτεκτονικών και SoCs

Δομημένος Προγραμματισμός (ΤΛ1006)

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Προγραμματισμός Υπολογιστών με C++

Εισαγωγή στην OpenGL

Προγραμματισμός Η/Υ. Προτεινόμενα θέματα εξετάσεων Εργαστήριο. Μέρος 1 ό. ΤΕΙ Λάρισας- Σχολή Τεχνολογικών Εφαρμογών Τμήμα Πολιτικών Έργων Υποδομής

Διάλεξη 11: Οργάνωση Προγραμμάτων σε Πολλαπλά Αρχεία

Επεξεργασία Αρχείων Κειµένου

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ

Προγραμματισμός Συστημάτων

Προγραμματισμό για ΗΜΥ

Τμήμα Πληροφορικής & Επικοινωνιών Δρ. Θεόδωρος Γ. Λάντζος

Προγραμματισμός H/Y Ενότητα 5: Συναρτήσεις. Επικ. Καθηγητής Συνδουκάς Δημήτριος Τμήμα Διοίκησης Επιχειρήσεων (Γρεβενά)

Πξνγξακκαηηζκόο Ι (ΗΥ120)

BloodShed Dev C++ Οδηγίες Χρήσης (Συγγραφέας: Πάρις Πολύζος)

Εργαστήριο 1: Επανάληψη Βασικών Εννοιών στη Γλώσσα C

procedure P ( < pars > ) < type> f( < pars > ) begin { < local vars > < local vars > < procedure body> < procedure body> end; }

Εισαγωγή στον Προγραμματισμό

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Εισαγωγή στη Σχεδίαση Λογισμικού

Διάλεξη 2η: Αλγόριθμοι και Προγράμματα

Προγραμματισμός Υπολογιστών με C++

Σε γενικές γραμμές, είναι καλή πρακτική να γράϕουμε προγράμματα C που αποτελούνται από πολλές και μικρές συναρτήσεις, παρά από λίγες και μεγάλες.

Δυναμική δέσμευση και αποδέσμευση μνήμης. Προγραμματισμός II 1

Προγραμματισμός Ι (ΗΥ120)

2.1 Αντικειµενοστρεφής προγραµµατισµός

ΜΥΥ- 402 Αρχιτεκτονική Υπολογιστών Μεταγλώτιση, σύνδεση

Εισαγωγή στον Προγραμματισμό με C++

Προγραµµατισµός Ι Εισαγωγή Πανεπιστήµιο Πελοποννήσου Τµήµα Πληροφορικής & Τηλεπικοινωνιών Προγραµµατισµός Ι Νικόλαος Δ. Τσελίκας

Εισαγωγή ΕΙΣΑΓΩΓΗ. Γεώργιος Παπαϊωάννου ( )

Προγραμματισμός Ι (ΗΥ120)

Εισαγωγή στην πληροφορική

Α Β Γ static; printf("%c\n", putchar( A +1)+2); B DB BD. int i = 0; while (++i); printf("*");

Ηλεκτρονικοί Υπολογιστές

Τεχνικές σχεδίασης προγραμμάτων, Προγραμματιστικά Περιβάλλοντα

lab13grades 449 PASS 451 PASS PASS FAIL 1900 FAIL Page 1

Κεφάλαιο , 3.2: Συναρτήσεις II. (Διάλεξη 12)

B. Ενσωμάτωση Ιθαγενών Μεθόδων

ΔΗΜΙΟΥΡΓΙΑ & ΧΡΗΣΗ ΒΙΒΛΙΟΘΗΚΩΝ

1 ΕΙΣΑΓΩΓΗ. Πρωταρχικοί Τύποι

Παράλληλη Επεξεργασία

Transcript:

Μεταγλώττιση και σύνδεση πολλαπλών αρχείων κώδικα Προγραμματισμός II 1 lalis@inf.uth.gr

Χρήση λογισμικού που ήδη υπάρχει Τα πολύπλοκα συστήματα αναπτύσσονται σταδιακά, «χτίζοντας» πάνω σε υπάρχουσα λειτουργικότητα Όταν αυτή παρέχεται από ένα κομμάτι υλικού, χρησιμοποιούμε μια φυσική διασύνδεση physical interface, π.χ., pins, cables Όταν αυτή παρέχεται από λογισμικό, χρησιμοποιούμε μια διασύνδεση προγραμματισμού (application) programming interface Σε κάθε περίπτωση, πρέπει να γνωρίζουμε και να τηρούμε τις προδιαγραφές χρήσης πρέπει να διαβάσουμε τα αντίστοιχα manuals Προγραμματισμός II 2 lalis@inf.uth.gr

0A1F68CED90B3020D85F1397C 5D90A3120D35F1197FFFF0131 D28CEB95F3420C85C11100 00B19D5711C210AA00B5A911F F2F8D9C5B3B20B851A0AC10 void init(int); int rnd(); hardware interface software interface Προγραμματισμός II 3 lalis@inf.uth.gr

hardware documentation void init(int seed); /* initialize random number generator with a seed; call once, before rnd */ int rnd(void); /* returns next random number */ software documentation Προγραμματισμός II 4 lalis@inf.uth.gr

Διεπαφή (προγραμματισμού) λογισμικού Αποτελείται (κυρίως) από δηλώσεις τύπων, σταθερών, μεταβλητών και συναρτήσεων Κάθε συνάρτηση χρησιμεύει για ένα συγκεκριμένο σκοπό, π.χ. την εκτέλεση κάποιας λειτουργικότητας Η σημασία / κωδικοποίηση των παραμέτρων και λειτουργικότητα των συναρτήσεων ορίζεται μέσω κατάλληλων προδιαγραφών (τεκμηρίωση) Για να χρησιμοποιήσουμε ένα τμήμα λογισμικού πρέπει να το συνδέσουμε κατάλληλα με το πρόγραμμα μας πρέπει να καλούμε τις συναρτήσεις σύμφωνα με τις προδιαγραφές που έχουν οριστεί Προγραμματισμός II 5 lalis@inf.uth.gr

Η λογική του «μαύρου κουτιού» Συνήθως μας ενδιαφέρει η λειτουργικότητα που θέλουμε να εκμεταλλευτούμε/χρησιμοποιήσουμε, όχι οι «εσωτερικές» λεπτομέρειες υλοποίησης της αν και αυτές πάντα ενδιαφέρουν τους μηχανικούς Black box principle: ξέρουμε πως μπορούμε/πρέπει να το χρησιμοποιήσουμε χωρίς να χρειάζεται να γνωρίζουμε το πώς «δουλεύει» Βασική αρχή ανάπτυξης πολύπλοκων συστημάτων Βασική αρχή πρακτικά για όλα τα τεχνολογικά προϊόντα που χρησιμοποιούμε σε καθημερινή βάση Προγραμματισμός II 6 lalis@inf.uth.gr

διασύνδεση Οδηγίες χρήσης: οι τροχοί στρίβουν προς την κατεύθυνση που στρίβεις το τιμόνι black box Προγραμματισμός II 7 lalis@inf.uth.gr

διεπαφή εσωτερική υλοποίηση λειτουργικότητας (που δεν βλέπει ο εξωτερικός παρατηρητής/χρήστης) περιγραφή διεπαφής (οδηγίες χρήσης) black box Προγραμματισμός II 8 lalis@inf.uth.gr

Η πολυκατοικία / στοίβα του λογισμικού user-level APIs εφαρμογή (application) system-level APIs βιβλιοθήκες & περιβάλλοντα εκτέλεσης λειτουργικό (OS) user system hardware specs υλικό (HW) Προγραμματισμός II 9 lalis@inf.uth.gr

Επαναχρησιμοποίηση λογισμικού Το μεγάλο «στοίχημα» στην βιομηχανία λογισμικού Ιδανικά, δεν χρειάζεται να ξαναγράψουμε κώδικα που έχει ήδη γραφτεί (από κάποιους άλλους) Προσέγγιση Α: αντιγράφουμε τον πηγαίο κώδικα, κάνοντας ίσως προσαρμογές για τις ανάγκες μας Προσέγγιση Β: καλούμε τον εκτελέσιμο κώδικα, σύμφωνα με τις οδηγίες χρήσης απαιτεί μηχανισμό σύνδεσης του δικού μας κώδικα με τον κώδικα που έχει ήδη γραφτεί/μεταφραστεί Προγραμματισμός II 10 lalis@inf.uth.gr

P1x compiler x -> y P1 y P2x compiler x -> y P2 y P1 y P2 y linker P y CPU y Προγραμματισμός II 11 lalis@inf.uth.gr

Στατική διασύνδεση P1 P linker P1 P P2 P linker P2 P Προγραμματισμός II 12 lalis@inf.uth.gr

Δυναμική διασύνδεση P1 linker P1 P P2 linker P2 P P Προγραμματισμός II 13 lalis@inf.uth.gr

Ανάπτυξη τμημάτων λογισμικού Σχεδίαση προγραμματιστικής διεπαφής: αποφασίζουμε το πως θα χρησιμοποιηθεί (προγραμματιστικά) η λειτουργικότητα Κατασκευή header file: ορισμός της διεπαφής με την μορφή ενός header file που θα χρησιμοποιηθεί (κυρίως) από τα προγράμματα «πελάτες» Κατασκευή υλοποίησης: σε ξεχωριστό αρχείο υλοποιούμε τη λειτουργικότητα, όπως ορίζεται στο header file, που μεταφράζεται για να δημιουργηθεί το τμήμα κώδικα που θα συνδεθεί (αργότερα) με τον κώδικα από τα προγράμματα «πελάτες» Προγραμματισμός II 14 lalis@inf.uth.gr

Header files στην C Οι διεπαφές προγραμματισμού στην C περιγράφονται μέσω header files, που περιέχουν ορισμούς τύπων δεδομένων δηλώσεις σταθερών και καθολικών μεταβλητών δηλώσεις συναρτήσεων Οι δηλώσεις μεταβλητών και συναρτήσεων πρέπει να έχουν τον προσδιορισμό extern υποδεικνύει στον μεταγλωττιστή ότι οι αντίστοιχες υλοποιήσεις τους δεν βρίσκονται στο ίδιο αρχείο Κάνοντας #include το header file, το πρόγραμμα μπορεί να χρησιμοποιεί τύπους, μεταβλητές και συναρτήσεις ενός ξεχωριστού τμήματος λογισμικού τον πηγαίο κώδικα του οποίου μπορεί να μην γνωρίζουμε Προγραμματισμός II 15 lalis@inf.uth.gr

Διασύνδεση Όταν ένα πρόγραμμα μεταφράζεται με βάση τις δηλώσεις ενός header file, ο κώδικας που παράγεται περιέχει αναφορές σε εξωτερικά αντικείμενα (μεταβλητές και συναρτήσεις) Για να παραχθεί ο τελικός εκτελέσιμος κώδικας, απαιτείται μια επιπλέον διαδικασία ενσωμάτωσης των ορισμών και υλοποιήσεων τους που βρίσκονται σε αρχείο που έχει ήδη μεταφραστεί Αυτή η διαδικασία ονομάζεται διασύνδεση (linking) Αφού ο μεταφρασμένος κώδικας συνδεθεί με όλα τα υπόλοιπα μεταφρασμένα τμήματα που παρέχουν τους ορισμούς / υλοποιούν των εξωτερικών μεταβλητών / συναρτήσεων, δημιουργείται το τελικό εκτελέσιμο Προγραμματισμός II 16 lalis@inf.uth.gr

/* foo.h */ extern int i; extern void boo(); υλοποιείται από χρησιμοποιείται από /* foo.c */ #include "foo.h" int i=0; /* main.c */ #include "foo.h" int main(int argc, char *argv[]) { void boo() { i++; boo(); i++; boo(); Προγραμματισμός II 17 lalis@inf.uth.gr

/* foo.h */ extern int i; extern void boo(); /* foo.c */ #include "foo.h" int i=0; void boo() { i++; /* foo.c */ #include /* foo.h foo.h */ extern int i; extern void boo(); int i=0; void boo() { i++; /* foo.o */ ------------ i -> 0 boo -> 5 ------------ 0 1 2 3 4 5 6 7 8 $ gcc foo.c c o foo.o Προγραμματισμός II 18 lalis@inf.uth.gr

/* foo.h */ extern int i; /* main.c */ #include "foo.h" extern void boo(); /* foo.h */ /* main.c */ #include "foo.h" int main( ) { boo(); i++; boo(); extern int i; extern void boo(); int main( ) { boo(); i++; boo(); /* main.o */ ------------ i ->??? boo ->??? ------------ 0 boo 1 i 2 3 i 4 boo $ gcc main.c c o main.o Προγραμματισμός II 19 lalis@inf.uth.gr

/* main.o */ ------------ i ->??? boo ->??? ------------ 0 boo 1 i 2 3 i 4 boo + /* foo.o */ ------------ i -> 0 boo -> 5 ------------ 0 1 2 3 4 5 6 7 8 /* test */ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 $ gcc main.o foo.o o test Προγραμματισμός II 20 lalis@inf.uth.gr

Περισσότερα για το extern Ο προσδιορισμός extern χρησιμοποιείται για τις δηλώσεις εξωτερικών μεταβλητών / συναρτήσεων, που ορίζονται / υλοποιούνται σε ένα άλλο αρχείο Η παράλειψη του extern σε δήλωση συνάρτησης (που δεν υλοποιείται τοπικά) οδηγεί σε αναζήτηση για «ταιριαστή» υλοποίηση της συνάρτησης στα αρχεία με τα οποία γίνεται σύνδεση του κώδικα Η παράλειψη του extern σε δήλωση (καθολικής) μεταβλητής δεν εγγυάται τοπικότητα Aν μια άλλη καθολική μεταβλητή δηλώνεται σε άλλο αρχείο με το ίδιο όνομα, κατά την διασύνδεση οι αναφορές σε αυτό το όνομα θα αφορούν την ίδια θέση μνήμης Προγραμματισμός II 21 lalis@inf.uth.gr

/* a.c */ int i; void incval() { i++; /* b.c */ extern void incval(); int main(int argc, char *argv[]) { extern int i; i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test $ $./test 15 16 $ Προγραμματισμός II 22 lalis@inf.uth.gr

/* a.c */ int i; void incval() { i++; /* b.c */ extern void incval(); int main(int argc, char *argv[]) { int i; i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test $ $./test 15 15 $ Προγραμματισμός II 23 lalis@inf.uth.gr

/* a.c */ int i; void incval() { i++; /* b.c */ extern int i; extern void incval(); int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test $ $./test 15 16 $ Προγραμματισμός II 24 lalis@inf.uth.gr

/* a.c */ extern int i; void incval() { i++; /* b.c */ int i; extern void incval(); int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test $ $./test 15 16 $ Προγραμματισμός II 25 lalis@inf.uth.gr

/* a.c */ extern int i; void incval() { i++; /* b.c */ extern int i; extern void incval(); int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test undefined reference to i $ Προγραμματισμός II 26 lalis@inf.uth.gr

όμως Προγραμματισμός II 27 lalis@inf.uth.gr

/* a.c */ int i; void incval() { i++; /* b.c */ int i; extern void incval(); int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test 15 16 $ Προγραμματισμός II 28 lalis@inf.uth.gr

/* a.c */ int i; void incval() { i++; /* b.c */ int i; void incval(); int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test 15 16 $ Προγραμματισμός II 29 lalis@inf.uth.gr

/* a.c */ int i; void incval() { i++; /* b.c */ int i; int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test $./test 15 16 $ Προγραμματισμός II 30 lalis@inf.uth.gr

Περισσότερα για το static Πως αποφεύγουμε μια καθολική μεταβλητή ή/και συνάρτηση που υλοποιούμε αποκλειστικά για τους σκοπούς του τοπικού κώδικα να «προσπελαστεί» (κατά λάθος) μέσα από κώδικα σε άλλο αρχείο; Η επιθυμητή τοπικότητα επιτυγχάνεται χρησιμοποιώντας τον προσδιορισμό static η εμβέλεια των καθολικών μεταβλητών και συναρτήσεων περιορίζεται στο αρχείο που δηλώνονται / υλοποιούνται Είναι αδύνατο να γίνει αναφορά σε αυτές (είτε επίτηδες είτε κατά λάθος) μέσα από κώδικα που βρίσκεται σε ένα άλλο αρχείο Προγραμματισμός II 31 lalis@inf.uth.gr

/* a.c */ int i; void incval() { i++; /* b.c */ static int i; extern void incval(); int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test $ $./test 15 15 $ Προγραμματισμός II 32 lalis@inf.uth.gr

/* a.c */ static int i; void incval() { i++; /* b.c */ int i; extern void incval(); int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test $ $./test 15 15 $ Προγραμματισμός II 33 lalis@inf.uth.gr

/* a.c */ static int i; void incval() { i++; /* b.c */ extern int i; extern void incval(); int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test undefined reference to i $ Προγραμματισμός II 34 lalis@inf.uth.gr

/* a.c */ int i; static void incval() { i++; /* b.c */ extern int i; extern void incval(); int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test undefined reference to incval $ Προγραμματισμός II 35 lalis@inf.uth.gr

/* a.c */ int i; static void incval() { i++; /* b.c */ extern int i; int main(int argc, char *argv[]) { i=15; incval(); $ gcc a.c c o a.o $ gcc b.c c o b.o $ gcc a.o b.o o test undefined reference to incval $ Προγραμματισμός II 36 lalis@inf.uth.gr

Ένα μικρό πρόβλημα... Όταν ένας κώδικας Α ορίζει μεταβλητές και υλοποιεί συναρτήσεις με σκοπό αυτές να χρησιμοποιηθούν μέσα από οποιοδήποτε άλλο κώδικα, τότε αυτές δεν μπορεί να δηλωθούν ως static Όταν ο κώδικας Α συνδεθεί με ένα άλλο κώδικα Β, οι μεταβλητές / συναρτήσεις του Α είναι διαθέσιμες για σύνδεση με αντίστοιχες (άμεσες ή έμμεσες) εξωτερικές δηλώσεις που υπάρχουν στον Β Αν οι εξωτερικές δηλώσεις του Β έχουν προκύψει από λάθος (π.χ. παράλειψη προσδιορισμού static σε δήλωση καθολικής μεταβλητής / συνάρτησης ή παράλειψη δήλωσης και υλοποίησης συνάρτησης), η διασύνδεση θα οδηγήσει σε λάθος αποτέλεσμα Προγραμματισμός II 37 lalis@inf.uth.gr

Η ρίζα του προβλήματος Αναφορά σε εξωτερικές μεταβλητές / συναρτήσεις γίνεται με βάση έναν επίπεδο χώρο ονομάτων, όπου δεν μπορεί να αποκλεισθεί η τυχαία χρήση του ίδιου ονόματος από διαφορετικά τμήματα κώδικα Ο προγραμματιστής δεν έχει τη δυνατότητα να προσδιορίσει το τμήμα λογισμικού το οποίο θα πρέπει να παρέχει τον ορισμό / υλοποίηση μιας εξωτερικής μεταβλητής / συνάρτησης Άλλες γλώσσες λύνουν το πρόβλημα, δίνοντας σε κάθε τμήμα λογισμικού ένα μοναδικό όνομα με βάση το οποίο άλλα τμήματα κώδικα μπορεί να αναφέρονται (χωρίς πιθανότητα λάθους) σε μεταβλητές και συναρτήσεις που αυτό προσφέρει Προγραμματισμός II 38 lalis@inf.uth.gr