C Programmierung: switch Anweisung mit zwei Argumenten?

Gast #927943
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
Doch, das ist Standard-C. Der Ausdruck a,b evaluiert sowohl a als auch
b und liefert als Ergebnis b. In diesem Fall wird (vielleicht zu
Debug-Zwecken) immer in case 10 verzweigt.
Gast
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
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...
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
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).
Gast
Es handelt sich um den Komma Operator und den gibts eigentlich nur bei 
C++ (nicht überladbar) oder beim normalen C mit Herstellerspezifischen 
Erweiterungen ist glaube ich nicht ANSI konform.
Moderator Persönliche Seite
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
> 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

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.