2015-06-29 11 views
2

Согласно определению точки последовательности, точки последовательности являются «указанных точек в последовательности выполнения называемых точек последовательности, все побочные эффекты предыдущих оценок гарантируется полная»последовательность точек и побочные эффекты

Так в ниже программа, все побочные эффекты оператора ++ должны были быть выполнены до перехода ко второй части оператора &&, то есть i должен быть увеличен до 1, так как && является точкой последовательности.

#include<stdio.h> 

int main() 
{ 
    int i=0,a; 
    a=i++&&1; 
    printf("%d",a); 
    getchar(); 
    return 0; 
} 

Ожидаемые результаты:

1 (1&&1=1)

фактический выход:

Почему не i приращение до 2-й части?

Использование тройной оператор также дает тот же результат:

#include<stdio.h> 

int main() 
{ 
    int i=0,a; 
    a=(i++)?1:0; 

    printf("%d",a); 
    getchar(); 
    return 0; 
} 

Тройной оператор также является точкой последовательности. Так не должно ли это давать результат 1 вместо 0?

ответ

5
i++ 

Оценивает предыдущее значение i.

В качестве значения побочного эффекта i прибавляется 1.

Так да точка последовательности есть, но выражение i++ вычисляется в 0 (хотя значение i является 1 в то же время)

Для ожидаемых результатов use ++i instead of i++.

От 6.5.2.4 Postfix инкремента и декремента в спецификации C11:

Результатом постфикса ++ оператор является значение операнда. Поскольку - побочный эффект, значение объекта операнда увеличивается (то, что есть, к нему добавляется значение 1 соответствующего типа). См. Обсуждения с добавочными операторами и составное назначение для информации об ограничениях, типах и преобразованиях и эффектах операций по указателям. Вычисление значения результата секвенировано перед побочным эффектом обновления сохраненного значения операнда . Что касается вызова функции с неопределенной последовательностью, , операция postfix ++ является отдельной оценкой. Postfix ++ на объекте с атомарным типом является операцией чтения-изменения-записи с использованием семантики памяти memory_order_seq_cst.)

98) В случае, когда указатель атомного объекта может быть сформирован и Е имеет целочисленный тип, Е ++ эквивалентно следующей кодовой последовательности, где Т является тип Е:

T *addr = &E; 
T old = *addr; 
T new; 
do { 
    new = old + 1; 
} while (!atomic_compare_exchange_strong(addr, &old, new)); 

со старым, являющимся результатом операции. Особое внимание следует уделить , если E имеет плавающий тип; см. 6.5.16.2.)