2012-04-05 14 views
5

Rozważmy następujący fragment kodu:Prawidłowe korzystanie z operatora warunkowego?

int i, k, m; 
k = 12; 
m = 34; 
for (i = 0; i < 2; i++) ((i & 1) ? k : m) = 99 - i; 
printf("k: %ld m: %ld\n\n", k, m); 

W tej głupiej przykład Wyrażenie warunkowe operator jest skrótem dla:

if (i & 1) k = 99 - i; else m = 99 - i; 

Mój kompilator nie narzekać i wykonując ten kawałek kodu daje Oczekiwana moc wyjściowa:

k: 98 m: 99 

Moje pytanie brzmi jednak, czy jest to ważny kod zgodny ze standardem C? Nigdy wcześniej nie widziałem czegoś podobnego.

+0

Jeśli kompiluje i wykonuje zgodnie z oczekiwaniami, to jest to najprawdopodobniej ważne. Jednak powinieneś zadać sobie pytanie, czy chcesz zachować taki kod, zwłaszcza jeśli nie jest on dotykany przez kilka lat i musisz zastanowić się, co robi, gdy wrócisz 5 lat w dół. –

Odpowiedz

8

Przypis 110 w standardzie C11:

Wyrażenie warunkowe nie daje lwartością.

I 06/05/16 ustęp 2:

Operator przypisania mają modyfikowalna lwartość jako jego lewego argumentu.

Więc nie, ten kod nie jest zgodny ze standardem C.

w C++ 11, to jest ważny:

Jeśli drugi i trzeci operandy są lwartościami i mają ten sam typ, wynik jest tego typu i jest lwartością.

To kolejny z tych zakurzonych zakątków, w których C i C++ różnią się znacznie. Jeśli twój kompilator nie generuje błędu, to domyślam się, że używasz kompilatora C++ z "trybem C" zamiast właściwego kompilatora C; MSVC?

+1

Myślę, że jest to poprawne C++. – hugomg

+0

Kompilowałem to jako kod C++, tak, nie w "trybie C" z MSVC++ 6.0. Nie próbowałem kompilować go w trybie C. Nawet jeśli jest poprawny, czy to w C, czy w C++, to nawet nie zamierzam go używać; to było coś, co wymyśliłem, gdy zastanawiałem się, jak zakodować program, który chciałem, i zacząłem się zastanawiać nad jego prawdziwością. Dzięki za odpowiedź! – zarulad

+0

@zarulad: chętnie pomożemy! –

1

Jest ważne, aby korzystać z warunkowego jako lval w C++, ale nie w C.

w C++ (ISO IEC 14882: 1998 (E) 5.16.4)

Jeśli drugi a trzecie operandy są lwartościami i mają ten sam typ, wynik jest tego typu i jest l-wartością.

Jeśli chcesz użyć podobną sztuczkę w C, należy stosować wskaźniki:

ISO/IEC 9899: TC2, 6.5.14.6

Jeśli oba drugi i trzeci są operandy wskaźniki lub jedna jest zerową stałą wskaźnika, a druga jest wskaźnikiem, typem wyniku jest wskaźnik do typu kwalifikowanego z wszystkimi kwalifikatorami typów typów wskazywanych przez oba operandy.

*((i & 1) ? &k : &m) = 99 - i; 
+0

A co z kwotowaniem @StephenCanon? –

+0

@PavanManjunath Znowu zdezorientowałem C i C++. Zaktualizowałem swoją odpowiedź, aby to odzwierciedlić. Dzięki! – dasblinkenlight

4

To nie jest legalne C, a kompilator, który je akceptuje, jest nieprawidłowy.Można jednak zrobić to samo z:

*((i & 1) ? &k : &m) = 99 - i; 

i staje się prawnym C.

Powiązane problemy