2.APR.2014/HvM; 21.MEI.2014/HvM;
13. Define versus Variabele
Dit onderwerp en het maken van bibliotheken behandel ik ook in de cursussen ‘Toolkit-CCOL’.
Voor meer informatie kunt u mij telefonisch of via het reactieformulier bereiken.
Is het u ook wel eens opgevallen dat voor de define FCMAX
ook wel eens FC_MAX
wordt geschreven (dus met een underscore)?
Bijvoorbeeld (zie rood vetgedrukt
):
void application(void) |
Maar het gaat in dit onderwerp om het gebruik van die underscore in de term FC_MAX
.
In het bestand *****SYS.H
(of soortgelijke benamingen) heeft u heel vaak #define …
staan. Zo'n define is een preprocessorcommando: Voor het compilatieproces vertaalt de preprocessor eerst alle defines naar de waardes die u daarbij heeft aangegeven, zoals in #define FCMAX 17
. U krijgt dan bijvoorbeeld de volgende ‘voorvertaling’:
Uw broncode: | wordt: | En dit maakt de preprocessor er van: |
#include “fcvar.c” |
Dit werkt goed zolang u geen bibliotheek van functies maakt. Wanneer u dat wel doet, dan compileert u uw standaardfunctie(s) tot een object- of library-file, en gebruikt u die file voor al uw applicaties. Het probleem is alleen, dat u tijdens het maken van de objectfile of uw bibliotheek, nog niet weet hoeveel fasecycli elke volgende regeling zal hebben. Sterker nog, dat zal per regeling anders zijn.
Nou kunt u dat Quick 'n Dirty oplossen door simpelweg een getal in te vullen dat groot genoeg is voor al uw toekomstige applicaties, bijvoorbeeld 32. Maar daarmee pompt u elke machineslag ontzettend veel ‘lucht’ door de CVN-interface. Dat claimt op straat veel processortijd en het vertraagt uw regeling enorm, echt niet netjes dus. En owee als u toch op een dag meer dan 32 fasecycli toepast… Weet u de fout dan nog te vinden? Als u al ziet dat er iets fout gaat!
Het is dus onmogelijk om een bibliotheekfile te maken, of een objectbestand te compileren dat u vervolgens in al uw applicaties gebruikt, indien in uw standaardfunctie een verwijzing staat naar een of meerdere #define …
met kruispuntdefinities. En dat geldt net zo goed voor FCMAX
als voor al die andere ‘MAX
'en’.
Hier biedt CCOL een oplossing voor: u kunt tijdens het compileren van een standaardfunctie voor uw bibliotheek gebruik maken van een variabele met de naam FC_MAX
.
Maar dan bent u er nog niet: doordat u bovenin uw broncode (de file met uw standaardfuncties) schrijft #include “fcvar.c”
voegt u een standaard CCOL-bestand in waarin alle arrays die bij de fasecycli horen op maat worden aangemaakt. Zo worden er bijvoorbeeld precies voldoende YM-elementen aangemaakt, exact evenveel SG-elementen, A-elementen, enzovoorts. In ons voorbeeld dus van elk element 17 stuks. En daar ontstaat nu juist het probleem wanneer er voor een volgende regeling een ander aantal fasecycli nodig is. Worden het er minder dan valt de schade nog wel mee, maar worden het er meer dan 17, dan krijgt u onherroepelijk problemen met te kleine tabellen, met zeer lastige fouten tot gevolg. Kom daar maar eens achter!
U lost dit probleem op door bovenin uw broncode niet naar #include “fcvar.c”
te verwijzen, maar naar #include “fcvar.
(de headerfile). In die headerfile worden geen arrays aangemaakt en dus ook niet op een vast aantal elementen vastgeprikt, maar er wordt slechts verwezen naar een externe array die tijdens het linken wordt samengevoegd met uw bibliotheekfile (h
”OBJ
of LIB
)! En daarom kunt u dan niet meer FCMAX
gebruiken (want dat is een keiharde waarde voor één bepaald kruispunt), maar u gebruikt FC
. Die ene underscore ertussen is een subtiel verschil, maar het maakt enorm veel uit. _
MAXFCMAX
verwijst naar een define, maar FC_MAX
verwijst naar een externe variabele. En de linker die voor elk project apart wordt aangeroepen zoekt later wel uit waar die variabele is gedefinieerd. Nieuwsgierig waar dat is? Dat gebeurt in de fcvar.c
die u in uw broncode voor elke regeling toch al opneemt! Want voor elke kruispuntapplicatie zal toch echt érgens de dimensie van uw regeling moeten worden gedefinieerd. Daar dus.
In het bovenstaande is het probleem is het voorbeeld met 17 fasecycli en FC_MAX
gebruikt. En voor elke andere dimensionering is er zo'n variabele beschikbaar die precies dezelfde waarde krijgt als de define waar die bij hoort: DP_MAX
, HE_MAX
, TM_MAX
, MLA_MAX
, enzovoorts.
Dit onderwerp en het maken van bibliotheken behandel ik ook in de cursussen ‘Toolkit-CCOL’.
Voor meer informatie kunt u mij telefonisch of via het reactieformulier bereiken.