avva: (Default)
[personal profile] avva
Гуляя по исходникам ядра Линукса в поисках информации о том, как в нём устроены real-time signals (см. 'man 7 signal', если вы не знаете, что это такое), я обнаружил случайно весьма удивительную конструкцию в C:

Оператор условного выбора ?:, но без второго операнда. То есть вместо обычного, скажем,

a = b ? c : d;

(что означает: если b, то присвоить a=c; иначе присвоить a=d), пишется, например, так:

a = b ? : d;

По контексту становится ясно, что это означает: если b, то a=b; иначе a=d.

(кстати, весьма неинтуитивно; самым очевидным кажется такая интерпретация: если b, то a не меняется, иначе a=d. Но, конечно, на самом деле такая интерпретация невозможна, т.к. согласно семантике языка выражение (b ? : d) должно иметь какое-то определённое значение)

Так вот, я такого никогда в жизни не видел, и не подозревал даже, что так можно писать. Теперь мне интересно, это разрешено каким-то стандартом, или это какое-то расширение gcc? Знает ли кто?

Пример "живого" использования в исходнике ядра Линукса см. например в файле net/ipv4/tcp.c, там их шесть штук (в 2.4.20 по крайней мере). Например:

val = (tp->keepalive_time ? : sysctl_tcp_keepalive_time)/HZ;

Re: программистское: C, Unix

Date: 2003-09-30 05:35 am (UTC)
From: [identity profile] arbat.livejournal.com

Замечательно. A теперь скажите, какой результат будет у

int i = 1;
int j = i++ ? i++ : i;


Re: программистское: C, Unix

Date: 2003-09-30 05:47 am (UTC)
From: [identity profile] homa.livejournal.com
В вашем случае результат будет таким: i = 3, j = 2.

В случае же
int i = 1;
int j = i++ ? : i;

результат будет несколько иным: i = 2, j = 2.

Т.е., во втором случае пропущенное выражение вновь вычисляться не будет -- во всяком случае, надеюсь на это. Иначе это уже не С, а, простите, Васик какой-то.

Re: программистское: C, Unix

Date: 2003-09-30 06:05 am (UTC)
From: [identity profile] homa.livejournal.com
Даже, наверно, i = 2, j = 1. Проверить не на чем.

Re: программистское: C, Unix

Date: 2003-09-30 12:12 pm (UTC)
From: [identity profile] arbat.livejournal.com

Так, наверное или точно? И как узнать?
"Проверить" - это не разговор.

Re: программистское: C, Unix

Date: 2003-10-01 12:21 am (UTC)
From: [identity profile] homa.livejournal.com
А вы, прошу пардону, спорите с моей первоначальной репликой? Или просто решили мне экзамен устроить? :) Придумать произвольную ситуацию, потребовать ее "в уме" проиграть, а потом еще и настаивать на точности? Как говаривал кто-то из физиков, "мой книжный шкаф знает больше меня, но физик не он, а я".

Re: программистское: C, Unix

Date: 2003-10-01 04:46 pm (UTC)
From: [identity profile] arbat.livejournal.com
Нет, не беспокойтесь, я Вас экзаменовать не собирался.
Можете посмотреть обсуждение в паралелльном треде.
Суть в том, что конструкция, в которой возможны сомнения, а необходимости нету никакой - не должна употребляться вообще.

Re: программистское: C, Unix

Date: 2003-09-30 09:15 am (UTC)
From: [identity profile] dvv.livejournal.com
Никакого - это не является программой на C :-)

А так - j будет равно 2, i будет равно 3. Стандарта C под рукой нет, а в C++ в 5.16/1 явно сказано, что все side effects of the first expression [...] happen before the second or third expression is evaluated.

Re: программистское: C, Unix

Date: 2003-09-30 12:10 pm (UTC)
From: [identity profile] arbat.livejournal.com

Отлично :-) Однако, Вам потребовалось заглянуть в стандарт, чтобы проверить порядок выполнения операторов. При этом Вы повели себя как интеллигентный человек, который знает, что порядок вообще говоря может быть всякий, что иногда он задан стандартом, а иногда нет, и который знает, куда посмотреть и держит хоть один из стандартов "под руками". Поздравляю, Вы входите в 1% людей, которые так себя ведут.

Беда в том, что Ваш код потом будет изучаться и, возможно, "улучшаться" другими, которые с вероятностью 99% не войдут в Ваш интеллигентский 1% :-)
Мораль - так писать не надо, и сокращенной версией пользоваться - тоже. Экономия копеечная, а потом кто-то в темном лесу напорется на сук.

Re: программистское: C, Unix

Date: 2003-09-30 12:21 pm (UTC)
From: [identity profile] dvv.livejournal.com
Хм? Мне потребовалось заглянуть в стандарт чтобы привести цитату, chapter и verse, что никак не говорит о моём немедленном знании или незнании сути данного конкретного вопроса. Что же касается моего стиля кодирования, так я стараюсь, чтобы он был максимально прозрачным и однозначным даже для кодеров с весьма общим представлением о языке, чтобы у любителей гадать о моих намерениях было как можно меньше материала для их любимого занятия.

Re: программистское: C, Unix

Date: 2003-09-30 12:27 pm (UTC)
From: [identity profile] arbat.livejournal.com
Вы хотите сказать, что были абсолютно, на 100% - уверены, что нету никаких проблем? :-)



Re: программистское: C, Unix

Date: 2003-09-30 12:31 pm (UTC)
From: [identity profile] dvv.livejournal.com
Я хочу сказать, что я абсолютно, на 100% был уверен, что с точки зрения языка никаких проблем в примере не было.

Re: программистское: C, Unix

Date: 2003-09-30 12:24 pm (UTC)
From: [identity profile] dvv.livejournal.com
В догонку:

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

December 2025

S M T W T F S
  123 4 56
78 9 10 11 1213
1415 1617181920
21 22 23 24 2526 27
2829 30 31   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 1st, 2026 11:27 pm
Powered by Dreamwidth Studios