FALSE = 0
TRUE = 1
Het zijn boleaanse algebra constanten: 0 is niet waar, 1 is waar.

#DEFINE is een constante van onbekende type defenitie.

Kan dus de volgende type defenities hebben;
REAL 16/32/64/80 bit of 8/16/32/64/128/512 bit, met of zonder voorteken.

TYPEDEF geeft alleen het type en bitbreedte aan.

ENUM is volgens mij toch gewoon het opsommen van 1 met de vorige waarde van de defenitie waarden in de enum structuur beginnend met 0 mits de defenitie al een waarde heeft?

Raar hoor dat in C wanneer false en true niet zijn gedefinieerd ze beiden de waarde 0 krijgen ????
Ik zou een foutmelding verwachten.

Doe mij maar Assembly, veel overzichtlijker en je weet wat de assembler en linker doen.

Op 22 december 2015 08:50:36 schreef rew:
[...]Stel jij schrijft:

for (i=0;i<25;i++)
  // iets voor 25x

Is dat goede code? Oh? Je wilt de definitie van i nog zien? OK... omdat i toch niet negatief kan worden:

unsigned int i;

Is het een stukje goede code?

Volgens de GCC jongens, is het met de laatste definitie NIET meer goed: "comparison between signed and unsigned object".

Dat komt omdat een constante altijd als een 'int' wordt gezien/gepromoveerd. Belachelijk inderdaad, dat is waar.

Maar het kan nog erger, effe een stom voorbeeld:

uint8_t andere_var = 0x10
uint8_t to_mask = 0xff;
uint8_t to_mask &= ~andere_var;

Als je bijvoorbeeld even een bitje wilt masken uit een byte. Dat is echt een ramp, je moet twee keer casten om het goed te krijgen. De compiler is te dom om de left-value te bekijken en alles in die context (uint8_t) te evalueren.

P.S.: Het is trouwens meestal zinloos om voor simpele teller een unsigned type te gebruiken of proberen zuinig te zijn door een 8-bit type te gebruiken voor indices. De code wordt op een 32-bitter vrijwel altijd groter, kijk maar eens naar de gegenereerde assembly.

Op 20 december 2015 13:53:49 schreef henri62:
Het bovenstaande voorbeeld is een knap staaltje van bagger code.
Waarom:
1- In de C89 definitie is het verboden om aan enums waardes toe te kennen, behalve de eerste entry.

Volgens mij mag dat wel, kan ten minste nergens vinden dat dit niet mag. Het hele nut van waardes toekennen zou dan ook een beetje weg zijn.

2- Dit slaat echt alles in die enum: LS_PWM_TIMER = !0,
Ik heb veel zooi gezien de laatste 30 jaar maar dit is echt totaal van de ratten besnuffelt.

Volgens mij niet zo veel mis mee. Een enum entry mag gespecificeerd worden met een constant expression, dus elke waarde die compile-time bepaald kan worden. Hooguit kan je je afvragen waarom er niet gewoon 1 staat en plaats van !0.

Zie: http://port70.net/~nsz/c/c89/c89-draft.html#3.5.2.2
En: http://port70.net/~nsz/c/c89/c89-draft.html#constant-expression

Ok.... Het verhaal gaat door.....

Als ik iets uitzet in de GUI waarmee je makkelijk de boel kan configureren genereert ie:

#define SERIAL_COMMUNICATION DISABLED

met ergens aan het begin een

#define DISABLED 0

En wat denk je dat een redelijke compiler doet met

#ifdef SERIAL_COMMUNICATION
... serial stuff ... 

of

#if defined (SERIAL_COMMUNICATION)
... serial stuff ... 

????

Wel de tweede, niet de eerste?

na
#define PIET 0

is PIET gedefinieerd toch?

Nee ifdef staat voor IF DEFINED. Dus in beide gevallen zal een redelijke compiler de serial stuff TOCH compileren. Inderdaad na "#define PIET 0" is PIET gedefineerd.

De source code die ik probeer te compileren bevat beide constructies (ifdef, if defined () ).

Ik snap niet hoe windows-mensen met die compilers kunnen leven die dit soort fratsen uithalen.

Ik snap niet hoe windows-mensen met die compilers kunnen leven die dit soort fratsen uithalen.

Je zegt het zelf al... Windows mensen. Inmiddels zo gehersenspoeld dat ze dit 'normaal' vinden...

Op 7 januari 2016 12:55:25 schreef rew:
Nee ifdef staat voor IF DEFINED. Dus in beide gevallen zal een redelijke compiler de serial stuff TOCH compileren.

Ik heb het effe met de locale gcc uitgeprobeerd (gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4). Hij doet wel de #if defined(), niet de #ifdef.

Ik heb effe geen zin om uit te zoeken wat de spec zegt, maar ik begrijp hieruit dat dat niet de bedoeling is?

Afijn, ik snap niet hoe linux-mensen daarmee kunnen leven ;-)

#define PIET 0

#ifdef PIET 
#warning "piet ifdef."
#endif

#if defined (PIET)
#warning "piet defined."
#endif

geeft:

testdef.c:6:2: warning: #warning "piet ifdef." [-Wcpp]
 #warning "piet ifdef."
  ^
testdef.c:10:2: warning: #warning "piet defined." [-Wcpp]
 #warning "piet defined."
  ^

Dus bij mij pakt ie wel alletwee. Raar.

ik was begonnen met toevoegen van code-stukken:

#ifdef IETS
#if !IETS
#undef IETS
#endif
#endif

maar uiteindelijk lijkt het toch iets anders te zijn geweest waar ik tegenaanliep: die code blijkt toch ook al te staan in de code die ik moet gebruiken.

Vals alarm. Sorry. Spuit 11 of zo.

Op 7 januari 2016 16:09:54 schreef blurp:
Ik heb het effe met de locale gcc uitgeprobeerd (gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4). Hij doet wel de #if defined(), niet de #ifdef.

AAARGH. Een 1-d-10-t fout.:


#define DISABLED 0
#define SERIAL_COMMUNICATION DISABLED
#ifdef SERIAL_COMMUNUCATION

Zoek de tikfout. Na verbetering voert de lokale gcc weer gewoon beiden uit.

Afijn, ik snap niet hoe linux-mensen daarmee kunnen leven ;-)

Linux (of gcc) is weer de beste uitvinding sinds gesneden brood ;-)

Op 7 januari 2016 11:52:11 schreef rew:
Ok.... Het verhaal gaat door.....

.......

Dat is toch volkomen normaal gedrag?
SERIAL_COMMUNICATION is nou eenmaal "ge-defined" (als DISABLED)

Wat eigenlijk gebruikt had moeten worden is het volgende lijkt mij?

#if (SERIAL_COMMUNICATION != DISABLED)
... serial stuff ... 

En mijn voorkeur zou dan uitgaan naar:

#if (SERIAL_COMMUNICATION == ENABLED)
... serial stuff ... 

Ik zit met "ingewikkelde" voorbeeldsources van ST. Die worden met ingewikkelde combinaties van defines geconfigureerd. En de ingewikkelde headers worden met een windows-gui-ding gemaakt.

In de eerste instantie ben ik de sources ingedoken en daar waar ik SERIAL_COMMUNICATION uitgezet had, een "#if 0" er omheengezet om te voorkomen dat het stuk TOCH gecompileerd werd, want in de binary zag ik dat ie die code toch aan het compileren was.

Die strategie om het op die manier aan het werk te krijgen heb ik na enige tijd laten varen: Te veel plekken, te veel kansen om het verkeerd te doen.

Uiteindelijk kwam ik er achter dat de compiler andere headers (serial aan) vond dan degene waar IK naar zat te kijken (serial uit). Domme fout.

Op 11 januari 2016 08:53:49 schreef RVL-Electronics:
[...]
Dat is toch volkomen normaal gedrag?
SERIAL_COMMUNICATION is nou eenmaal "ge-defined" (als DISABLED)

Wat eigenlijk gebruikt had moeten worden is het volgende lijkt mij?

#if (SERIAL_COMMUNICATION != DISABLED)
... serial stuff ... 

En mijn voorkeur zou dan uitgaan naar:

#if (SERIAL_COMMUNICATION == ENABLED)
... serial stuff ... 

Het is maar hoe je het bekijkt, als je #ifdef (of #if defined, is exact hetzelfde) gebruikt kun je de macro definieren maar maak deze dan ook leeg en geef deze geen waarde, zo dus:


#define SERIAL_COMMUNICATION

En dan later


#ifdef SERIAL_COMMUNICATION
.... code
#endif

Gebruik je macros met een waarde behoor je ook een compare uit te voeren. Zoals RVL-Electronics hierboven zegt.

Verder is het beter altijd met de FALSE waarde te comparen (idg DISABLED), TRUE is meestal op de meest raarste manieren gedefinieerd waardoor een compare de mist in kan gaan.
Verder is in het bovenstaande voorbeeld DISABLED/ENABLED ook tricky, wie zegt dat deze macros ook in de set van SERIAL_COMMUNICATION voor kunnen komen? Dan hadden die ook SERIAL_ENABLED/SERIAL_DISABLED moeten heten.

Alle andere combinaties moeten niet gebruikt worden want die zijn zeer verwarrend, bij code reviews reden om die af te keuren.

Verder is het gebruik van #ifdef handig als je met commandline argumenten werkt voor gcc of welke compiler dan ook.
Met -D<MACRONAAM> definieer je namelijk de variable maar de value is niet bekend, en doet er ook niet toe. Vrijwel alle compilers ondersteunen dit.

Later is bij veel compilers ook de constructie -DMACRONAAM=VALUE geimplementeerd wat ook handig is.

Verder heeft deze discussie helemaal niets met Linux of Windows van doen, het is een algemeen C probleem dat je er makkelijk een zooitje van kunt maken. Dat geld trouwens voor alle programmeertalen.

@burp: Verder ben ik het er ook niet mee eens dat gcc de beste compiler is.