#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.
#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).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
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 intte 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.