extern în C++

Declară o variabilă sau funcție definită în altă parte (de obicei în alt fișier) sau cere legare în stilul limbajului C.

Sintaxă
extern int variabila;            // declarație, definiția e în alt loc
extern "C" void functie(int);    // legare în stil C

Ce face extern

Un program mare are mai multe fișiere .cpp. Dacă o variabilă globală este definită într-un fișier (int vizite = 0;), celelalte fișiere o pot folosi după ce o declară cu extern int vizite;. extern spune „există, dar nu aici”: nu se alocă memorie nouă.

extern "C" cere ca o funcție să fie legată după regulile limbajului C, fără „decorarea” numelor pe care o face C++. Se folosește când apelezi biblioteci scrise în C sau când scrii funcții care vor fi apelate din C.

Exemple

Exemplul 1: Declarație cu extern, definiție mai jos

În programele reale, declarația extern stă într-un fișier antet, iar definiția într-un singur fișier .cpp. Aici, pentru simplitate, sunt în același fișier.

#include <print>

extern int vizite;  // declarație: variabila există undeva

void inregistreaza_vizita() {
    ++vizite;
}

int vizite = 0;     // definiția (o singură dată în tot programul)

int main() {
    inregistreaza_vizita();
    inregistreaza_vizita();
    std::println("Vizite: {}", vizite);
}

Rezultat

Vizite: 2

Exemplul 2: extern „C”

Funcția aduna_c este legată în stil C, deci poate fi apelată și dintr-un program scris în C. Din C++ se apelează normal.

#include <print>

extern "C" int aduna_c(int a, int b) {
    return a + b;
}

int main() {
    std::println("2 + 3 = {}", aduna_c(2, 3));
}

Rezultat

2 + 3 = 5

Greșeli frecvente

  • Scrii extern int x = 5; crezând că e doar o declarație. Cu inițializare devine definiție; dacă mai există una în alt fișier, primești eroarea „duplicate symbol” la legare.
  • Declari extern int vizite; dar uiți definiția. Totul se compilează, iar eroarea apare abia la legare: „undefined symbol”.

Comenzi înrudite

  • static: Are trei sensuri: variabilă locală care își păstrează valoarea între apeluri, membru comun al clasei sau nume vizibil doar în fișierul curent.
  • inline: Permite ca o funcție sau variabilă să fie definită în mai multe fișiere (de obicei într-un antet) fără eroare de definiție dublă.
  • namespace: Grupează funcții, clase și variabile sub un nume comun, ca să nu se încurce cu alte nume identice din program sau din biblioteci.
  • #include: Directivă a preprocesorului care copiază conținutul unui fișier antet în locul ei, ca să poți folosi funcțiile și clasele declarate acolo.