ProgrammatieC ontwikkelaar

Vertel over de belangrijkste verschillen tussen const en #define voor het definiëren van constanten in de C-taal. Wanneer en waarom elk van de benaderingen gebruiken, met voorbeelden van typische fouten?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

#define is een preprocessor-directief dat alle gevallen van de identificator vervangt door de waarde voor de compilatie. Het creëert geen variabelen, kent geen types, controleert geen grenzen en respecteert niet de scope.

const is een qualifier die een echte variabele creëert, maar deze geblokkeerd is voor schrijfbewerkingen na initialisatie. De const-variabele heeft een type, scope, neemt deel aan debugging en kan veiliger zijn. Dergelijke variabelen worden geplaatst in het .rodata-segment of op de stack/in het RAM.

Wanneer en waarom te gebruiken:

  • #define — voor eenvoudige scalair waarden die nodig zijn op compileertijd, vooral wanneer deze worden gebruikt in preprocessor-voorwaarden of arraygroottes (#define SIZE 16).
  • const — voor waarden die typeveilig moeten worden doorgegeven, gedebugd en veilig moeten worden geëxporteerd (in headerbestanden, intermodule).
  • Voor pointers naar strings en arrays is het beter om const te gebruiken.

Voorbeeld:

#define PI 3.14159 const double G = 9.81; int arr[PI]; // FOUT! PI is geen integer int arr2[G]; // FOUT! G is geen compileertijd waarde

Vals vragen.

Vraag: Werkt const int a = 10; als compileertijd constante voor het maken van een array: int arr[a];?

Antwoord: Nee. In de C-taal is const een qualifier, maar de variabele wordt tijdens runtime gemaakt en geïnitialiseerd, niet tijdens de compilatie, dus de grootte van de array moet een literatuur of een expressie zijn die door de compiler bekend is. Gebruik #define, of enum { SIZE = 10 };.

Voorbeeld van een fout:

const int a = 5; int arr[a]; // In C89/90 zal dit niet werken (VLA's verschenen in C99, maar niet overal)

Geschiedenis

In de mediaserver probeerden ze const int te gebruiken voor het instellen van buffers, denkend dat dit een "compileertijd constante" was. Op één compiler (GCC, C99) werkte alles, maar op de meeste was er een compilatiefout (VLA wordt niet ondersteund), ze herschreven snel naar #define.


Geschiedenis

In platformafhankelijke code definieerden ze een string via #define NAME "MyApp", gebruikten dit op verschillende plaatsen en vergaten het tussen haakjes te plaatsen. Na het toevoegen van karakters aan de string zonder expliciete haakjes, kregen ze onjuiste resultaten, wat leidde tot vreemde bugs in de logs.


Geschiedenis

In een project met meerdere modules definieerden ze een constante via #define op twee plaatsen met verschillende waarden (copy-paste). Het resultaat was dat de modules met verschillende constanten werkten, wat leidde tot gegevensnon-conformiteiten, die alleen werden hersteld tijdens zorgvuldige debugging.