2013-04-08 1 views
12

Я знаю, что это выглядит знакомо, но это доведено до меня как проблема в тесте Microsoft, чтобы набирать стажеров. Мне кажется, что y=++y не соответствует стандарту, но я думаю, что было бы лучше быть уверенным (не уверен, что я лучше тех, кто пишет эти тесты в MS). Поэтому я прошу вашего совета. Считаете ли вы, что подобные выражения соответствуют стандарту и не приводят к неопределенным поведением?`y = ++ y`, соответствует ли этот стандарт? [, который появляется в тесте от Microsoft]

#include <stdio.h> 
int main(){ 
    int a = 10; 
    int b = 10; 
    a = ++a; //What ??? 
    b = b++; //What ??? 
    printf("%d %d\n",a,b); 
    return 0; 
} 

gcc жалуется на него, когда используется для компиляции с -Wsequence-point. (Это явно не указано, является ли это C или конкретная проблема C++.)

Но только четыре ответа при условии:

a) 10 10 
b) 11 10 
c) 10 11 
d) 11 11 

Хотя один не ограничивается, чтобы выбрать только один ответ (так может быть, я должен выбрать все четыре?)

Ну, на мой взгляд, между самоинструментацией и присваиванием нет точки последовательности. Таким образом, это нарушает спецификацию. Не так ли?

+0

Вы хотите получить ответ в терминах C++ 03 или C++ 11? Они рассуждают по этому поводу по-разному. –

+0

Вы правы. Это неопределенное поведение. – Art

+0

Да, это UB, но я все равно возьму b) как ответ: P –

ответ

9

Они оба четко определены в соответствии с C++ 11. C++ 11 даже не имеет точек последовательности, поэтому предупреждение о последовательности, очевидно, устарело. Оператор присваивания накладывает последовательность на свои аргументы.

Edit:

Хотя каждый может согласиться, что i = ++i теперь вполне определенное поведение, это довольно нетривиальная решить определенность в i = i++.Наглядно, я должен описать, как хорошо определены, но стандарт четко говорится, что

i = i++ + 1; 

является UB, и я не вижу в + 1 делает никакой разницы здесь.

Короче говоря, если бы вы хотели ответить на этот вопрос, вам нужно было бы стать экспертом по совершенно нетривиальным правилам секвенирования C++ 11, которые, как представляется, я не являюсь, но кажется, что ответ «Ничего из вышеперечисленного, потому что UB».

+0

@DeadMG Не могли бы вы ответить на дополнительный вопрос, так как вы ответили на исходный вопрос: не должен ли результат «11 12» в C++ 11? – lapk

+0

Нет. Почему? А также задайте другой вопрос. – Puppy

+0

@DeadMG Поскольку 'b = 11;' и 'b = b ++;' делает 'b' по-прежнему равным' 11', и у нас есть пост-инкремент, который делает 'b' равным' 12' в 'printf' .. Извините, я не думал, что это стоит отдельного вопроса, и я не мог понять, почему в первоначальном списке не было такого выбора ... Возможно, я что-то недопонимаю, просто подумал прояснить. – lapk

4

В соответствии со стандартом C++ 03,
Оба приведенных ниже утверждений приводит к непредсказуемому поведению:

a = ++a; 
b = b++; 

Как правильно указано, г ++ указывает ниже предупреждения:

предупреждение: операция «a» может быть неопределенной [-Последовательная точка]

Обратите внимание, что в случае UB ответ может быть любым, кроме (a), (b), (c), (d).
В идеале должна быть опция «неопределенного поведения» в тестовом вопросе. Но часто человек, который подготавливает вопрос, просто компилируется в компиляторе XYZ и представляет его.

Это связанное сообщение SO, объясняющее Undefined Behavior and Sequence Points.

+0

+1 хотя я бы склонен жаловаться на качество реализации компилятора, если он выдает код, чтобы заставить демонов вылететь из моего носа в этом случае. Да, это будет стандартно, но это все равно сосать. –

+1

'a = ++ a;' не является UB в C++ 11. Это UB в C++ 03. –

+2

Вы ошибаетесь, так как C++ 11 меняет это. – Puppy

-4

Я думаю, что это D), так как ++ a означает приращение a, а затем выполнить операцию, так что это будет как делать a = 11. b ++ означает выполнение операции и затем увеличение, поэтому вы будете назначать b = 10, но затем b увеличивается, давая ему значение b = 11.

Ну, для пуристов: Это ничего не значит «ничего, а что-нибудь», но это его поведение. Я тестировал его (используя визуальные C++ и g ++), и мой ответ правильный: a = 11 и b = 11.

+0

Это не означает «что-то», а затем «что-то». –

+0

Ну, мне не нужен эмпирический результат *. Почти все популярные компиляторы, используемые в настоящее время, демонстрируют такое поведение. Но я хочу знать, требуется ли это ** для этого или просто метод резервного копирования, который может быть принят или нет. – phoeagon

+2

Невозможно «проверить» неопределенное поведение, потому что оно не определено, и каждая реализация может делать все, что он хочет. (Это независимо от исходного вопроса.) –

0

a = ++ a; b = b ++; Эти операции считаются не определенными. Каждый компилятор может делать по своему усмотрению. вывод зависит от компилятора, который рассмотрел вопросник.

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

  • Нет связанных вопросов^_^