Hoe het externe trefwoord correct te gebruiken in C

Mijn vraag gaat over wanneer naar een functie moet worden verwezen met het trefwoord externin C.

Ik zie niet in wanneer dit in de praktijk moet worden gebruikt. Terwijl ik een programma aan het schrijven ben, worden alle functies die ik gebruik beschikbaar gesteld via de header-bestanden die ik heb toegevoegd. Dus waarom zou het handig zijn om externte gebruiken om toegang te krijgen tot iets dat niet zichtbaar was in het headerbestand?

Ik zou kunnen denken aan hoe externonjuist werkt, en zo ja, corrigeer me dan.

Ook.. Moet je iets externals het de standaarddeclaratie is zonder het trefwoord in een headerbestand?


Antwoord 1, autoriteit 100%

externwijzigt de koppeling. Met het trefwoord wordt aangenomen dat de functie / variabele ergens anders beschikbaar is en wordt het oplossen uitgesteld aan de linker.

Er is een verschil tussen externop functies en op variabelen.

Voor variabelenwordt de variabele zelf niet geïnstantieerd, d.w.z. er wordt geen geheugen toegewezen. Dit moet ergens anders gebeuren. Het is dus belangrijk als u de variabele ergens anders vandaan wilt importeren.

Voor functiesvertelt dit de compiler alleen dat koppeling extern is. Aangezien dit de standaard is (u gebruikt het sleutelwoord staticom aan te geven dat een functie niet gebonden is met externe koppeling), hoeft u deze niet expliciet te gebruiken.


Antwoord 2, autoriteit 67%

externvertelt de compiler dat deze data ergens gedefinieerd is en verbonden zal worden met de linker.

Met behulp van de reacties hier en het praten met een paar vrienden hier is het praktische voorbeeld van het gebruik van extern.

Voorbeeld 1 –om een valkuil te laten zien:

stdio.h:

int errno;

myCFile1.c:

#include <stdio.h>
// Code using errno...

myCFile2.c:

#include <stdio.h>
// Code using errno...

Als myCFile1.oen MyCFile2.ozijn gekoppeld, heeft elk van de c-bestanden afzonderlijke kopieën van errno. Dit is een probleem omdat dezelfde errnobeschikbaar zou moeten zijn in alle gekoppelde bestanden.

Voorbeeld 2 –De oplossing.

stdio.h:

extern int errno;

stdio.c:

int errno;

myCFile1.c:

#include <stdio.h>
// Code using errno...

myCFile2.c:

#include <stdio.h>
// Code using errno...

Als nu zowel myCFile1.oals MyCFile2.ozijn gekoppeld door de linker, verwijzen ze beide naar dezelfde errno. Dus de implementatie oplossen met extern.


Antwoord 3, autoriteit 12%

Er is al aangegeven dat het trefwoord externoverbodig is voor functies.

Wat betreft variabelen die door compilatie-eenheden worden gedeeld, moet u ze declareren in een headerbestand met het sleutelwoord extern, en ze vervolgens definiëren in een enkel bronbestand, zonder het sleutelwoord extern. Het enkele bronbestand moet het bestand zijn dat de naam van het kopbestand deelt, voor de beste praktijk.


Antwoord 4, Autoriteit 6%

Vele jaren later ontdek ik deze vraag. Na het lezen van elk antwoord en opmerkingen, dacht ik dat ik een paar details kon verduidelijken … dit kan nuttig zijn voor mensen die hier door Google zoeken.

De vraag is specifiek over het gebruik van externfuncties, dus ik zal het gebruik van externmet globale variabelen negeren.

Laten we 3 functie-prototypes definiëren:

// --------------------------------------
// Filename: "my_project.H"
extern int function_1(void);
static int function_2(void);
       int function_3(void);

Het koptekstbestand kan als volgt worden gebruikt door de hoofdbroncode:

// --------------------------------------
// Filename: "my_project.C"
#include "my_project.H"
void main(void) {
    int v1 = function_1();
    int v2 = function_2();
    int v3 = function_3();
}
int function_2(void) return 1234;

Om te compileren en te koppelen, moeten we function_2in hetzelfde broncodebestand definiëren waar we die functie noemen. De twee andere functies kunnen in verschillende broncode worden gedefinieerd *.Cof ze kunnen zich in een binair bestand bevinden (*.OBJ, *.LIB, *.DLL), waarvoor wij mogelijk niet de broncode hebben.

Laten we de header opnieuw opnemen my_project.HIn een andere *.CBestand om het verschil beter te begrijpen. In hetzelfde project voegen we het volgende bestand toe:

// --------------------------------------
// Filename: "my_big_project_splitted.C"
#include "my_project.H"
void old_main_test(void){
    int v1 = function_1();
    int v2 = function_2();
    int v3 = function_3();
}
int function_2(void) return 5678;
int function_1(void) return 12;
int function_3(void) return 34;

Belangrijke functies om op te merken:

  • Als een functie is gedefinieerd als staticin een header-bestand, moet de compiler/linker een instantie van een functie met die naam vinden in elke module die dat include-bestand gebruikt.

  • Een functie die deel uitmaakt van de C-bibliotheek kan in slechts één module worden vervangen door een prototype alleen in die module opnieuw te definiëren met static. Vervang bijvoorbeeld elke aanroep naar mallocen freeom een geheugenlekdetectiefunctie toe te voegen.

  • De specificatie externis niet echt nodig voor functies. Wanneer staticniet wordt gevonden, wordt altijd aangenomen dat een functie externis.

  • Echter, externis niet de standaard voor variabelen. Normaal gesproken moet elk headerbestand dat variabelen definieert die zichtbaar zijn in veel modules, externgebruiken. De enige uitzondering zou zijn als een header-bestand gegarandeerd wordt opgenomen vanuit één en slechts één module.

    Veel projectmanagers zouden dan eisen dat een dergelijke variabele aan het begin van de module wordt geplaatst, niet in een headerbestand. Sommige grote projecten, zoals de videogame-emulator “Mame”, vereisen zelfs dat dergelijke variabelen alleen verschijnen boven de eerste functie die ze gebruikt.


Antwoord 5, autoriteit 5%

In C wordt externgeïmpliceerd voor functie-prototypes, aangezien een prototype een functie declareert die ergens anders is gedefinieerd. Met andere woorden, een functie-prototype heeft standaard externe koppeling; het gebruik van externis prima, maar is overbodig.

(Als statische koppeling vereist is, moet de functie worden gedeclareerd als static, zowel in het prototype als in de functiekop, en deze zouden normaal gesproken beide in hetzelfde .c-bestand moeten staan).


Antwoord 6, autoriteit 3%

Een heel goed artikel dat ik vond over het trefwoord extern, samen met de voorbeelden: http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/

Hoewel ik het er niet mee eens ben dat het gebruik van externin functiedeclaraties overbodig is. Dit zou een compiler-instelling moeten zijn. Dus ik raad aan om de externte gebruiken in de functiedeclaraties wanneer dat nodig is.


Antwoord 7, autoriteit 2%

Als elk bestand in je programma eerst wordt gecompileerd tot een objectbestand, dan worden de objectbestanden aan elkaar gekoppeld, je hebt externnodig. Het vertelt de compiler “Deze functie bestaat, maar de code ervoor is ergens anders. Geen paniek.”


Antwoord 8

Alle declaraties van functies en variabelen in headerbestanden moeten externzijn.

Uitzonderingen op deze regel zijn inline-functies gedefinieerd in de header en variabelen die – hoewel gedefinieerd in de header – lokaal moeten zijn voor de vertaaleenheid (het bronbestand waarin de header wordt opgenomen): deze moeten static.

In bronbestanden mag externniet worden gebruikt voor functies en variabelen die in het bestand zijn gedefinieerd. Plaats lokale definities gewoon met staticen doe niets voor gedeelde definities – het zijn standaard externe symbolen.

De enige reden om externin een bronbestand te gebruiken, is om functies en variabelen te declareren die in andere bronbestanden zijn gedefinieerd en waarvoor geen headerbestand is opgegeven.


Het declareren van functie-prototypes externis eigenlijk niet nodig. Sommige mensen houden er niet van omdat het alleen maar ruimte verspilt en functieverklaringen al de neiging hebben om lijnlimieten te overschrijden. Anderen vinden het prettig omdat op deze manier functies en variabelen op dezelfde manier kunnen worden behandeld.


Antwoord 9

Functies die daadwerkelijk gedefinieerdzijn in andere bronbestanden, mogen alleen in headers worden verklaard. In dit geval moet u externgebruiken bij het declarerenvan het prototype in een koptekst.

Meestal zullen uw functies een van de volgende zijn (meer als een best practice):

  • statisch (normale functies die dat niet zijn)
    zichtbaar buiten dat .c-bestand)
  • statische inline (inlines van .c of .h
    bestanden)
  • extern (verklaring in headers van de
    volgende soort (zie hieronder))
  • [geen enkel trefwoord] (normaal
    functies die bedoeld zijn om te worden gebruikt met behulp van
    externe verklaringen)

Antwoord 10

Als je die functie hebt gedefinieerd op een andere dll of lib, zodat de compiler de linker moet zoeken om hem te vinden. Typisch geval is wanneer u functies aanroept vanuit de OS API.

Other episodes