Het typesysteem in C ontstond al aan het begin van de taal (eind jaren 60 - begin jaren 70). Strikte statische typechecking stelt de compiler in staat om de compatibiliteit van typen van variabelen, expressies en teruggegeven waarden vóór de uitvoering van het programma te controleren.
Geschiedenis van de kwestie:
Statische typechecking werd geïntroduceerd om vooraf fouten te voorkomen die anders pas tijdens de uitvoering ontdekt zouden worden. In de loop der tijd is het typesysteem in C geleidelijk complexer geworden ter ondersteuning van nieuwe platforms en programmeerstijlen.
Probleem:
Type-incompatibiliteit kan leiden tot onvoorspelbare gevolgen: geheugenbeschadiging, onjuiste berekeningen, of een crash van het programma. Zonder statische controle is het moeilijk om dergelijke situaties te vermijden.
Oplossing:
C code controleert de typen van variabelen en expressies tijdens de compilatiefase. Bijvoorbeeld, je kunt geen pointer naar int toewijzen aan een variabele van het type float* zonder expliciete typecast. Dit voorkomt veel fouten.
Voorbeeldcode:
int x = 5; double y = 3.14; y = x; // impliciete type-uitbreiding van int -> double int* p = &x; double* q = (double*)p; // toegestaan, maar onveilig!
Belangrijkste kenmerken:
Waarom kan in C elke pointer naar void worden gecast en weer terug zonder informatieverlies?*
De C-standaard garandeert dat een pointer van elk type naar void* en terug kan worden gecast zonder informatieverlies. Dit wordt bijvoorbeeld gebruikt in functies van de standaardbibliotheek (malloc, memcpy). Echter, casting van void* terug naar een onjuist type leidt tot onvoorspelbaar gedrag.
Hoe vindt impliciete typeconversie plaats bij rekenkundige bewerkingen tussen int en float?
C "promoveert" automatisch het kleinere type naar een breder type, meestal naar double of float. Als bijvoorbeeld int en float worden opgeteld, wordt int omgezet in float vóór de operatie.
int a = 10; float b = 2.5f; float c = a + b; // a wordt eerst geconverteerd naar float
Is het waar dat een pointer naar void niet gedereferenceerd kan worden?
Ja, een pointer naar void wijst naar gegevens van een onbepaalde type en kan niet direct worden gedereferenceerd, omdat de compiler de grootte van het type niet kent. Voor dereferencen is het nodig om het naar een specifiek type te casten:
void* ptr = ...; int x = *(int*)ptr;
Doorgeven van pointers van verschillende types aan een functie die void* accepteert, zonder correcte casting:
void print_value(void* data) { printf("%d\n", *(int*)data); // fout, als data een double* is } double d = 1.5; print_value(&d); // onjuist
Voordelen:
Nadelen:
Gebruik van statische typechecking en expliciete conversies met controle:
void print_int(void* data) { if (data) { printf("%d\n", *(int*)data); } } int value = 42; print_int(&value);
Voordelen:
Nadelen: