2009-06-10 20 views
0

Tenir compte de cette construction C qui vérifie les erreurs avant de faire le travail réel:Utilisez l'instruction switch C pour la gestion des erreurs

int function(struct Context *context,struct Connection *conn) 
{ 
    int retval; 

    switch(0) 
    { 
     case 0: 
      retval = BUFFER_INACTIVE; 
      if(conn->mSocket == -1) 
       break; 
      retval = BUFFER_FULL; 
      /* Is there enough room to add ? */ 
      if((context->mMaxBufferSize - conn->mSendPacketLength) < aPacketLength) 
       break; 

      /* Is the send packet buffer half sent? */ 
      if(conn->mSendPacketLength > 0 && conn->mSendPacketPos != conn->mSendPacket) 
       break; 

      /* Do some work here */ 
      retval = BUFFER_DONE; 
    } 
    /* Do some things before returning */ 
    printf("%d",retval); 
    return retval; 
} 

Voulez-vous considérer cela comme une lisible être? Est-ce que les alternatives, en utilisant goto ou empilés if() seraient mieux?

+0

Je n'ai vraiment pas peur des gotos ... J'ai du mal de cette construction et je voulais des retours. – 0x6adb015

Répondre

5

Je ne l'ai jamais vu la solution de commutation, mais je l'ai fait des trucs comme ça:

do { 
    err = func(); 
    if(err) break; 
    err = func2(); 
    if(err) break; 
    ... 
} while(0); 
if(err) { 
    // handle errors 
} 

Mais quelle est la différence entre cela et ceci:

err = func(); 
if(err) goto done; 
err = func2(); 
if(err) goto done; 
... 
done: 
if(err) { 
    //handle errors; 
} 

La première est que le deuxième réécrite pour éviter d'utiliser le mot-clé goto, et je dirais que la solution goto est plus lisible. Il m'a fallu un certain temps, mais j'ai réussi à me convaincre que goto ne sont pas toujours mal. En fin de compte, je préfère simplement utiliser if instructions si possible, car il rend le code plus lisible, mais goto si nécessaire.

4

Je dirais que c'est moins lisible. Je pense que l'utilisation d'une instruction if ou même d'un goto serait une approche beaucoup plus appropriée. Utiliser goto n'est pas la fin du monde et est parfaitement acceptable et approprié pour la gestion des erreurs.

http://kerneltrap.org/node/553/2131

+0

Je suis d'accord que si quelqu'un voit ce commutateur(), il faudrait un certain temps pour déchiffrer ce qu'il fait. – 0x6adb015

0

Je vous recommande d'utiliser while (true) au lieu du commutateur:

while(true) 
{ 
      retval = BUFFER_INACTIVE; 
      if(conn->mSocket == -1) 
        break; 
      retval = BUFFER_FULL; 
      /* Is there enough room to add ? */ 
      if((context->mMaxBufferSize - conn->mSendPacketLength) < aPacketLength) 
        break; 

      /* Is the send packet buffer half sent? */ 
      if(conn->mSendPacketLength > 0 && conn->mSendPacketPos != conn->mSendPacket) 
        break; 

      /* Do some work here */ 
      retval = BUFFER_DONE; 
      break; 
} 
+1

Je pense que while (true) amènera quelqu'un à s'attendre à un looping, ce qui n'est définitivement pas le cas. En utilisant "do {...} while (0);" est plus idiomatique. –

+0

D'accord, faites {...} while (0); est une meilleure façon de le faire. –

+2

do {... while (0); est également la meilleure pratique pour contenir la portée dans une macro ... – Jamie

0

Une autre alternative est de l'envelopper dans une fonction et de revenir au lieu de casser. C'est souvent une mauvaise idée car cela finit par ajouter une couche d'abstraction inutile. Cependant, dans certains cas, cela peut simplifier les choses.

-1

Une alternative est d'utiliser ifs en cascade:

u8 u8IsOk; 

u8IsOk = Func1(); 

if(u8IsOk) 
{ 
    /* Do some stuff...*/ 
    u8IsOk = Func2(); 
} /* if */ 

if(u8IsOk) 
{ 
    /* Do some stuff...*/ 
    u8IsOk = Func3(); 
} /* if */ 

... et ainsi de suite. Pas aussi efficace que d'autres méthodes, mais évite l'imbrication excessive, goto, break, while (0) et plusieurs retours.

+0

Pourquoi la downvote? –

+2

Peut-être que c'est à cause de la mauvaise notation pseudo-hongroise ... –

+0

J'ai été surpris de voir à quel point les gens semblent ne pas l'aimer. C'est assez commun dans les logiciels embarqués. –