2013-08-13 1 views
3

Будет ли это юридическим кодом или нарушением каких-либо правил?Пропуск переключающих шкафов через ложный цикл является действительной операцией?

switch (expr) 
{ 
    do 
    { 
     case 6: 
      /*...*/ 

      if (/*...*/) 
       break; 
     case 7: 
      /*...*/ 

    } while (0);  

    case 9: 
     /*...*/ 

     break; 

    default: 
     break; 
} 

Будет ли это законным способом выполнения дела 6, за которым следует случай 7, но только если выполнены некоторые условия? Или это приведет к неопределенному поведению и позволит носовым драконам выйти из переключателя? стр. мой вопрос относится к c99.

EDIT:

Что я хочу сделать, это следующее: предположим, корпус 9, должен быть выполнен в everycase. Если expr равно 6, я должен выполнить 6 при некоторых условиях 7 и после этого 9 или если expr равно 7 его 7-> 9 , поэтому я просто хочу пропустить 7, если выполняются некоторые условия, но я не могу изменить порядок 6,7,9.

EDIT2:

Я не ищу для альтернативного soloution, я просто заинтересован в поведении этого фрагмента.

Если коммутатор заявление имеет связанную с ним делом или по умолчанию метки в пределах сферы действия идентификатора с переменно модифицированным типом, весь оператор выключатель должен находиться в пределах рамки этого идентификатора.

из ISO/IEC 9899: ТС3 6.8.4.2-> 3

Позволяет мне не уверены в своем поведении. Но я не уверен, что будет нацелен на код, похожий на мой фрагмент.

+1

Можете ли вы описать, что вы на самом деле пытаетесь сделать? Я считаю, что это правильный код, но может быть какое-то лучшее решение, возможно? –

+0

Устройство Duff смешивает 'do' /' while' и 'switch' аналогично. Я бы сказал, что ваш пример не включает UB. –

+0

@Mats Petersson done :) – dhein

ответ

0

Действительно да; делать то, что вы хотите? Я сомневаюсь в этом.

Предполагая break S вы клали в являющемся только тех, то предполагая, что компилятор не получает в полное состояние (не неправдоподобно откровенно, особенно если у вас есть оптимизации появились), то произойдет следующее

case 9:: запускает свой блок и продолжает default: запускает свой блок и продолжает case 7: запускает свой блок несколько раз навсегда case 6: протекание его блок, может быть 7, повторяет навсегда

Чтобы сделать то, что вы хотите, удалите do..while и поместите блок if в конец 6 вокруг 7, возможно, чтобы поставить защитник, чтобы проверить, находитесь ли вы в случае 6 или 7.

switch (expr) 
{ 
    case 6: 
     /*...*/  
      break; 
    case 7: 
     if (expr==7 || !/*...*/) 
     { 
     /*...*/ 
     } 
    case 9: 
     /*...*/ 

     break; 

    default: 
     break; 
} 

Однако это не то, как я это сделаю. Вероятно, это может привести к тому, что упаковка его в дочерние функции будет иметь смысл:

void handle6() { /*...*/ } 
void handle7() { /*...*/ } 
void handle9() { /*...*/ } 

switch (expr) 
{ 
    case 6: 
    handle6(); 
    if(/*...*/) handle7(); 
    handle9(); 
    break; 
    case 7: 
    handle7(); 
    case 9: 
    handle9(); 
    break; 
    default: 
    /*...*/ 
} 

- еще один способ, который, вероятно, более ясен.

и для полноты ...

switch(expr) 
{ 
    case 6: 
     /*...*/ 
     if(/*...*/) goto case_9; 
    case 7: 
     /*...*/ 
    case 9: 
case_9: 
     /*...*/ 
     break; 
    default: 
     break; 
} 
+0

способ использования функций взорвал бы мой код, который бы мог быть понятен, потому что у коммутатора гораздо больше случаев, чем в моем фрагменте;) – dhein

+0

@Brian Cain Если бы я использовал функции, как он описывает во втором фрагменте, мне придется например: 'case 9: func1(); -> func4(); -> func7() -> funcx(); break;' и это много вызовов функций только для каждого случая. и исходный файл также не станет меньше – dhein

+0

. Нет ограничений на количество вызовов функций в каждом случае. Это здорово, если мы сможем сделать исходные файлы меньше, но если это будет стоить того, чтобы понять программу, то это пирровая победа. Цель программы - сообщить человеку, что должен делать компьютер. –

1

Хотя я считаю, что приведенный выше код является действительным, я хотел бы сделать его более явным:

case 6: 
    ... 

    /* fall through */ 
case 7: 
    if (expr != 6 || condition_to_run_7) 
    { 
     do whatever 7 does; 
    } 
    if (should_not_do_9) 

case 9: 
    ... 
    break; 

}

В качестве альтернативы, которая является чистое решение: двигаться, что 6, 7 и 9 случаев выполняются в отдельные функции и вызывают соответствующие функции (более одного раза, если необходимо) в инструкции switch и имеют надлежащий «разрыв» после каждого случая ...

+0

способ использования функций взорвал бы мой код, который был бы нескромным, потому что у коммутатора гораздо больше случаев, чем в моем фрагменте;) – dhein

+2

Еще больше причин использовать функции ... –

+0

нет, потому что условия для этого случая должны выполняться после который. вряд ли вложен. так что я должен был сделать так, как 100 случаев в каждом случае, например, 20 if statements – dhein

1

Возможно, я один из тех дурные программисты. Я не уверен в стандартах, но я делал такие вещи, когда это было необходимо. Тем не менее, если бы я хотел сделать то, что вы заявили в вашем вопросе, я бы что-то вроде этого:

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) 
{ 
    int iCnt, iTmp; 

    for(iCnt = 1; argc > iCnt; iCnt ++) 
    { 
     iTmp = (int) strtol(argv[iCnt], NULL, 10); 

     switch(iTmp) 
     { 
      case 6: 
       printf("Case 6\n"); 

      /* change this condition to whatever suits you */ 
      if (argc - 1 == iCnt) 
      { 
      case 7: 
       printf("Case 7\n"); 
      } 

      case 9: 
       printf("Case 9\n"); 
      default: 
       printf("Default case\n"); 
     } 

     printf("\n"); 
    } 

    return 0; 
} 

т.е. если заявление более свойственный здесь ИМО.

+0

Ну, отлично, но помните, я спрашиваю об этом - это ссылка на код lega на cstandard, особенно из опубликованного правила. – dhein