C Programmierung: switch Anweisung mit zwei Argumenten?

Gast #927943
Lesenswert?

Hallo,
bei einem Beispielprogramm von TI bin ich über eine switch - Anweisung 
gestolpert, der 2 Argumente übergeben werden. Kann mir das jemand 
erklären?
Es steht dabei, dass es eine effiziente Implementierung wäre, aber ich 
werde nicht so ganz schlau daraus.



// Timer_A3 Interrupt Vector (TAIV) handler
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A(void)
{
  switch (TAIV, 10)        // Efficient switch-implementation
  {
    case  2:                                // TACCR1
      P1OUT ^= 0x01;                        // Toggle P1.0
      TACCR1 += 50000;                      // Add Offset to TACCR1
      break;
    case  4: break;                         // TACCR2 not used
    case 10: break;                         // Overflow not used
  }
}
Gast #927992
Lesenswert?

Ob das ganze ANSI-(oder wie auch immer)konform ist, weiß ich nicht.
Es ist jedenfalls eine Spezialität des IAR-Compilers, der unter 
bestimmten Voraussetzungen aus der switch-Anweisung einen optimierten 
Code generiert.

In neueren Versionen müsste es eigentlich heißen:
1
// Timer_A3 Interrupt Vector (TAIV) handler
2
#pragma vector=TIMERA1_VECTOR
3
__interrupt void Timer_A(void)
4

5
switch (__even_in_range(TAIV, 10))          // Efficient switch-implementation
6
  {
7
    case  2:                                // TACCR1
8
      P1OUT ^= 0x01;                        // Toggle P1.0
9
      TACCR1 += 50000;                      // Add Offset to TACCR1
10
      break;
11
    case  4: break;                         // TACCR2 not used
12
    case 10: break;                         // Overflow not used
13
  }

Der TIMERA1_VECTOR hat mehrere Quellen, wobei in TAIV vermerkt ist, 
welche Quelle gerade in der ISR bearbeitet wird. Es ist hierbei bekannt, 
dass der Wert in TAIV maximal 10 sein kann (->...(TAIV,10)...) und 
geradzahlig ist (__even_in_range).
Dann kann eine Sprungtabelle angelegt werden, auf die einfach 
zugegriffen werden kann, indem der aktuelle TAIV-Wert auf den Program 
Counter addiert wird. Die Sprungtabelle verzweig dann in die 
unzterschiedlichen cases.
Das ist alles ;-)
Gast #928029
Lesenswert?

Den CCE kenne ich nicht.
Ich denke aber, dass das (zumindest in dieser Notation) nur im IAR 
funktioniert. Vielleicht hat der CCE aber einen ähnlichen "Mechanismus". 
Da sollte aber dessen User-Guide weiterhelfen...
#928233
Lesenswert?

Das scheint schon Ansi-C zu sein, der gcc mäkelt jedenfalls auch net. 
Ist übrigens teils schon witzig was der C Standard hergibt, der 
Klassiker:
1
        n = (anzahl + 3) / 4;
2
 
3
        switch(anzahl % 4) {
4
        case 0:        do { ziel[stelle] = quelle[stelle]; stelle++;
5
        case 3:             ziel[stelle] = quelle[stelle]; stelle++;
6
        case 2:             ziel[stelle] = quelle[stelle]; stelle++;
7
        case 1:             ziel[stelle] = quelle[stelle]; stelle++;
8
                       } while(--n > 0);
9
        }
Moderator Persönliche Seite #928446
Lesenswert?

I_ H. wrote:

> Das scheint schon Ansi-C zu sein, der gcc mäkelt jedenfalls auch net.

Er wird aber dabei etwas völlig anderes tun. ;-)  Wie yalu schon
geschrieben hat, wird er zwar das Register TAIV auswerten, aber
anschließend fest zum Wert 10 in der switch-Anweisung verzweigen.

In der aktuellen IAR-Doku findet man darüber auch nichts mehr, sondern
nur die weiter oben beschriebene (Pseudo-)Funktion __even_in_range(),
die ganz offensichtlich eigens für diese Eigenheit der MSP430s
gezimmert worden ist (und die es dann auch nur bei der MSP430-Version
gibt).
Moderator Persönliche Seite #928858
Lesenswert?

Andreas Kaiser wrote:

>> Es handelt sich um den Komma Operator und den gibts eigentlich nur bei
>> C++ (nicht überladbar)
>
> Ist normales C seit K&R.

Nur halt nicht in dieser etwas eigenwilligen semantischen Ausdeutung
da ganz oben. ;-)  Aber daher haben sie's ja offenbar auch korrigiert
und stattdessen den korrekten Weg mit __even_in_range() gewählt.
Gast #928877
Lesenswert?

> Es handelt sich um den Komma Operator und den gibts eigentlich nur bei
> C++ (nicht überladbar)

type& operator , ( type )
{
}

Der MS-compiler kann das, ob es sinn macht ist eine andere Frage.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren