C-fråga, bitmanipulation.

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
hawkan
Inlägg: 2586
Blev medlem: 14 augusti 2011, 10:27:40

Re: C-fråga, bitmanipulation.

Inlägg av hawkan »

Vilket jävla skitsnack.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45175
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: C-fråga, bitmanipulation.

Inlägg av TomasL »

Öh, nej.
Skall du skriva buggfri klar kod, så använder du inte preprocessorn, den är enbart till för de lata och de inkompetenta.
Sannolikt har de som tycker man skall använda preprocessorn till makron och liknande blivit allvarligt fel-lärda.
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: C-fråga, bitmanipulation.

Inlägg av Icecap »

Jag använder macron en del - men mycket sällan till programfunktioner. Det sker dock att jag ersätter en lite kryptisk funktion med ett mer fattbart namn och enklare skrivsätt - vilket främjar läsbarheten i programmet.

Exempel:
#define Printout(X) RS232B_Send_String((_UBYTE*)X)
#define Debugout(X) RS232A_Send_String((_UBYTE*)X)

Jag har även använd macron i ett nyligt program där jag anger varje funktions-pin med port hhv. portpin. (Typ 'A' och '3' för PORTA3)
Då kan jag med de två data samla ihop de olika funktioner så som vilken TRIS-bit (PIC-µC) som ska ställas till ingång, vilken portpinne som ska läsas och skrivas, allt baserat på en enda definition av varje funktions-pinne.

Men att använda macron i större utsträckning anser jag är kontraproduktivt, har man "konstiga" funktioner/uträkningar i ett program är det bättre att kommentera dom än att gömma dom i en macro.

Sedan har jag ju noll utbildning inom elektronikdesign, programmering, billagning, svetsning, matlagning, syning, massage osv. - men klarar mig rimligt ändå. Faktisk är det enda jag har ett gesällbrev som "Elektronikreparatör".
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45175
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: C-fråga, bitmanipulation.

Inlägg av TomasL »

Findecanor skrev:Hur då menar du att de inte går att debugga?
Vad jag menar är att 1:
Du får ett bygg-fel, pga ett felaktigt makro, det finns ingen kompilator mig veterligen som talar om att du har fel i makrot, dvs du får spendera timmar med att leta i olika listningar innan du hittar det (har själv hamnat i den situationen, tog ett par tre dar att hitta felet), GCC som kompilator.
När du debuggar, så expanderas inte makrona till C-koden de motsvarar (inte vad jag sett i GCC i alla fall), vilket gör att du defakto inte kan debugga koden, detta eftersom preprocessormakron hanteras i en klump, och inte som individuella programrader, preprocessorn var ursprungligen tänkt att hantera superglobala konstanter och villkorlig kompilering
, typ.
mAVRick
Inlägg: 319
Blev medlem: 19 mars 2013, 12:43:43
Ort: Östersund

Re: C-fråga, bitmanipulation.

Inlägg av mAVRick »

Det finns definivt goda skäl för att vid vissa tillfällen använda macron. Inte minst x-macron kan vara väldigt användbara. Sen kan jag hålla med att man bör undvika att strössla med macron.
Att helt avfärda preprocessorn, det är bara nonsens.
BJ
Inlägg: 8185
Blev medlem: 11 april 2007, 08:14:53
Ort: En_stad

Re: C-fråga, bitmanipulation.

Inlägg av BJ »

Det finns ju skräckexempel på hur man inte
ska göra makron. Flera rader långa, med
?-varianten för att skriva if-satser.
Är nästan omöjligt att läsa.

Men så behöver man ju inte göra.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45175
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: C-fråga, bitmanipulation.

Inlägg av TomasL »

mAVRick skrev:Det finns definivt goda skäl för att vid vissa tillfällen använda macron. Inte minst x-macron kan vara väldigt användbara. Sen kan jag hålla med att man bör undvika att strössla med macron.
Att helt avfärda preprocessorn, det är bara nonsens.
Nej, man skall vara extremt försiktig, enbart vid absoluta nödfall, när det inte går att lösa på annat sätt, typ villkorlig kompilering, och inget annat.
mAVRick
Inlägg: 319
Blev medlem: 19 mars 2013, 12:43:43
Ort: Östersund

Re: C-fråga, bitmanipulation.

Inlägg av mAVRick »

Hmm.. för när du har en drös olika villkor för hur koden ska kompileras, då blir det lätt att debugga?
Nja du, du får ju ha din åsikt, men jag anser ändå att det finns betydlig mer användning av preprocessorn än så.
Även macron kan vara väldigt användbara. Man kan göra mer än bara 'inline funktioner' med macron.
Om något så är man lat om man helt avfärdar preprocessorn.
Senast redigerad av mAVRick 15 juni 2018, 22:36:03, redigerad totalt 2 gånger.
Användarvisningsbild
AndLi
Inlägg: 17050
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: C-fråga, bitmanipulation.

Inlägg av AndLi »

Adam Dunkels protothread måste spela i en egen klass när det kommer till att definiera obskyra macro...

Genialt och skrämmande på en och samma gång....
Macron

Kod: Markera allt

#define PT_THREAD(name_args)  char name_args
#define PT_BEGIN(pt)          switch(pt->lc) { case 0:
#define PT_WAIT_UNTIL(pt, c)  pt->lc = __LINE__; case __LINE__: \
                              if(!(c)) return 0
#define PT_END(pt)            } pt->lc = 0; return 2
#define PT_INIT(pt)           pt->lc = 0
Exempel

Kod: Markera allt

static
PT_THREAD(example(struct pt *pt))
{
  PT_BEGIN(pt);
  
  while(1) {
    PT_WAIT_UNTIL(pt,
      counter == 1000);
    printf("Threshold reached\n");
    counter = 0;
  }
  
  PT_END(pt);
}
blir

Kod: Markera allt

static
char example(struct pt *pt)
{
  switch(pt->lc) { case 0:
 
  while(1) {
    pt->lc = 12; case 12:
    if(!(counter == 1000)) return 0;
    printf("Threshold reached\n");
    counter = 0;
  }
 
  } pt->lc = 0; return 2;
}
Nu var kanske inte detta exempel det mest komplexa, men det blir rätt snyggt ...
Har dock aldrig använt det i verkligheten, bara fått det beskrivit på någon kurs av Adam...
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45175
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: C-fråga, bitmanipulation.

Inlägg av TomasL »

Jo, men Dunkel är väl berömd för att kunna tvinga in komplexa program i synnerligen små processorer, typ webserver och TCP/IP på under 1KB (tror det var 512B eller så), vilket naturligtvis kräver synnerligen o-ortodox och obegriplig programmering.
Men det är väl inte det vi gör normalt.
Vet inte om det är denna varianten, http://dunkels.com/adam/miniweb/
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43149
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: C-fråga, bitmanipulation.

Inlägg av sodjan »

> Allting som inte är direkt utläsbart i koden är felaktigt, när du läser koden så skall du direkt, ihop med
> kommentarerna kunna följa koden, med makron så kan du inte på något sätt följa vad som händer.

Om du vet vad makrot står för och vad den gör, så är det ju som vilken annan kod
som helst att läsa. Det finns mycket normalt C kod där jag också har väldigt svårt
att följa vad som händer, även utan makron.

Och det där kan ju även säga om varje vanligt funktionsanrop. Du måste kolla funktionens
kod, ifall du inte redan vet vad den gör (eller snarare vet hur den gör det den gör).
Gimbal
Inlägg: 7878
Blev medlem: 20 april 2005, 15:43:53

Re: C-fråga, bitmanipulation.

Inlägg av Gimbal »

Även om man förstår precis vad varje rad gör så betyder det inte att man förstår varför man gör det. Att beskriva själva idén, algoritmen bakom allt bit-trixande är minst lika viktigt.
Findecanor
Inlägg: 982
Blev medlem: 2 juli 2010, 23:04:07

Re: C-fråga, bitmanipulation.

Inlägg av Findecanor »

Visst går det att skjuta sig i foten med preprocessorn. Men C erbjuder många andra sätt att skjuta sig i foten också.
I alla dessa olika fall gäller det att man har lärt sig vilka fallgropar som finns och har lite disciplin och inte skriver fulkod.

Vi snackar om det här enkla macrot:

#define SET_LOW_BITS(bits) ((1<<(bits))-1)

Fallgroparna i det här exemplet:
- Får inte vara mellanslag mellan SET_LOW_BITS och (
- Man bör ha som vana att alltid wrappa parametrar på högra sidan i paranteser
- Man bör ha som vana att alltid ha paranteser runt hela uttrycket

Har man lärt sig de sakerna, och har de man jobbar med lärt sig de sakerna så kan man använda macron tycker jag. Det finns mängder av artiklar på nätet att läsa om vad farorna är och hur man skriver macron på ett säkert sätt.
När man är van så gör man det automatiskt.
Men som sagt... inline-funktioner har inte dessa fallgropar och är att föredra ... när de finns.
gkar
Inlägg: 1453
Blev medlem: 31 oktober 2011, 15:28:29
Ort: Linköping

Re: C-fråga, bitmanipulation.

Inlägg av gkar »

TomasL skrev:
Findecanor skrev: När du debuggar, så expanderas inte makrona till C-koden de motsvarar (inte vad jag sett i GCC i alla fall), vilket gör att du defakto inte kan debugga koden, detta eftersom preprocessormakron hanteras i en klump, och inte som individuella programrader, preprocessorn var ursprungligen tänkt att hantera superglobala konstanter och villkorlig kompilering
, typ.
De flesta kompilatorer kan dumpa källkoden direkt efter preprocessorn till fil.
Den kompilerar du sedan och trycker in i din debugger om du vill.
Dvs det ser ut som om du manuellt expanderat alla macron själv.
Då fattar alla debuggrar koden.
gkar
Inlägg: 1453
Blev medlem: 31 oktober 2011, 15:28:29
Ort: Linköping

Re: C-fråga, bitmanipulation.

Inlägg av gkar »

mounte skrev:Du var nästan helt rätt ute i din approach du behöver bara subtrahera 1
(1<<n) - 1
i princip lika som XorXaX
Prestanda är tydligen viktigt:

På ARM, jag chansar på det!, borde detta, men jag har inte provat, ge koden. (Det är några år sedan jag jobbade som kompilator)
mov r2,#1
rsb r0, r2, r2 lsl r3

Dvs, om du inte har alltför högt registertryck och du skall göra detta många gånger i en loop, kommer 1 att vara statiskt i r2.

Alltså mov försvinner för alla varv utom det första.

RSB, (reverse subtract) däremot, tar typiskt 2 cykler eftersom det är en 4 operandsinstruktion och registerbanken inte har tillräcklig bandbredd för det.
På nyare maskiner (cortex A8+) skulle jag gissa, utan att ha kollat, att r3 dessutom har en early cykel, dvs register r3 behöver vara tillgängligt en cykel i förväg.

Det tar ju fortfarande två cykler vilket är lite drygt att vänta på när man har bråttom.

Om r3 inte är slumpmässiga tal, utan tex 0 till 8 efter varandra, är den enkla lösningen att förladda ett register med 0xff00ff00 och rotera det varje gång.

Rotation tar bara en cykel, men kan oftast inte genereras av de flesta C kompilatorer eftersom det inte finns någon operator direkt för det.
Ibland finns det macros, ibland finns det inline funktioner. Ibland får man använsa assembler...

I asm:
mov r0, r0 rol #1 ; Detta tar bara en cykel!
Tittar man i ett lite större spann, om vitar ARM som exempel, kanske man kan ta bort ytterligare en cykel genom att få operationen gratis när man gör något annat.

Appropå tabellslagning, som kan vara bra ibland, krävs ofta "early cycles" för att beräkna adresseringsmodet, samt att datat kommer efter 2-3 eller ännu fler "late cycles".
Har vi något vettigt att göra undertiden funkar det ju, men har vi inte det blir det bubblor i pipelinen och det vill vi inte ha!
Skriv svar