Szukaj…


Uwagi

Źródło: Jaka jest różnica między definicją a deklaracją?

Źródło (dla słabych i silnych symboli): https://www.amazon.com/Computer-Systems-Programmers-Perspective-2nd/dp/0136108040/

Zrozumienie deklaracji i definicji

Deklaracja wprowadza identyfikator i opisuje jego typ, czy jest to typ, obiekt lub funkcja. Deklaracja jest tym, czego kompilator potrzebuje, aby zaakceptować odwołania do tego identyfikatora. Są to deklaracje:

extern int bar;
extern int g(int, int);
double f(int, double); /* extern can be omitted for function declarations */
double h1();           /* declaration without prototype */
double h2();           /* ditto                         */

Definicja faktycznie tworzy / implementuje ten identyfikator. Właśnie tego linker potrzebuje, aby połączyć referencje z tymi jednostkami. Są to definicje odpowiadające powyższym deklaracjom:

int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
double h1(int a, int b) {return -1.5;}
double h2() {}  /* prototype is implied in definition, same as double h2(void) */

Zamiast deklaracji można zastosować definicję.

Jednak musi być zdefiniowany dokładnie raz. Jeśli zapomnisz zdefiniować coś, co gdzieś zostało zadeklarowane i do którego się odwołuje, linker nie wie, do czego prowadzić link i narzeka na brakujące symbole. Jeśli zdefiniujesz coś więcej niż jeden raz, linker nie wie, do której z definicji odwołuje się odnośnik, i skarży się na powielone symbole.

Wyjątek:

extern int i = 0;  /* defines i */
extern int j;  /* declares j */

Ten wyjątek można wyjaśnić za pomocą pojęć „Silne symbole vs Słabe symbole” (z perspektywy linkera). Więcej informacji można znaleźć tutaj (Slajd 22).

/* All are definitions. */
struct S { int a; int b; };             /* defines S */
struct X {                              /* defines X */
    int x;                              /* defines non-static data member x */
};
struct X anX;                                  /* defines anX */


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow