2016-08-20 1 views
4

Так что это в C99:Не может быть метка в объявлении среднего потока в C?

label: 
    int ret = function(of, stuff); 

дает ошибку во время компиляции, в то время как это:

label: 
    ; 
    int ret = function(of, stuff); 

работает просто отлично.

Является ли это ошибкой компилятора? Или это ошибка в определении стандарта C? Или, если это часть стандарта C99, возможно, кто-то встанет на защиту стандарта C, чтобы утверждать, что это имеет смысл?

+2

«Возможно, кто-то встанет на защиту стандарта C, чтобы утверждать, что это имеет смысл» - ну, вы наверняка пришли в нужное место. –

+0

Почему эти близкие голоса ...: -S - справедливый вопрос, который я до сих пор помню очень хорошо ...:-) – alk

+0

Видимо, вопросы о языке программирования не о программировании? –

ответ

7

Этикетки, которые определены в N1256 6.8.1 Обозначенные маркировки могут содержать только заявления.

Syntax 
1  labeled-statement: 
      identifier : statement 
      case constant-expression : statement 
      default : statement 

int ret = function(of, stuff); является декларация, которая определена в N1256 6.7 декларациях и не является утверждением.

отчетность определены ниже в N1256 6.8 отчетности и блоков:

Syntax 
1  statement: 
      labeled-statement 
      compound-statement 
      expression-statement 
      selection-statement 
      iteration-statement 
      jump-statement 

compound-statement так называемые блоки , который является 0 или более декларации и заявления, окруженные {}.

expression-statement - это нуль или одно выражение, определенное в N1256 6.5. Выражения, за которыми следует точка с запятой, как i++;. Выражение в синтаксисе определено в N1256 6.5.17 Оператор запятой.

selection-statement является if и switch заявление.

iteration-statement является while, do-while и for заявление.

jump-statement является goto, continue, break и return заявление.

Как вы видите, объявления не являются утверждением, поэтому вы не можете помещать метки в объявления.

+0

Итак, у вас может быть, например. 'label: {int ret = function (of, stuff); } '. – detly

4

Возможно, ошибка в спецификации - когда она была изменена, чтобы разрешать выражения и объявления смешиваться в блоке (а не требовать всех объявлений перед операторами), он также должен был быть изменен, чтобы разрешать метки в объявлении, но это не так. Артефакт о том, как язык развивался с течением времени.

Это не серьезная проблема, как вы ее обнаружили, так как вы можете обойти ее тривиально, поставив метку на пустой оператор перед объявлением.

+0

Возможно, обратите внимание, что те же самые искажения и обходные пути предшествуют C99 для конечных случаев (или меток) в коммутаторе. Я предполагаю, что требование последующего утверждения устраняет некоторую двусмысленность или облегчает жизнь парсеру. – doynax

+0

Я не удивлюсь, если цель запрещения заявлений, которые следуют за заявлениями, была фактически гарантией того, что невозможно перейти от точки, следующей за объявлением, до точки до объявления, не выходя из сферы действия этого объявления. Требование, чтобы все переменные в * функции * предшествовали любому исполняемому коду (как это делали некоторые компиляторы до C89), упрощает генерацию кода, но я не думаю, что правила C89 предлагают какое-либо реальное преимущество, за исключением того, что код, передающий управление точке прежде чем декларация должна обязательно оставить свой объем. – supercat

Смежные вопросы