программистское: C, Unix
Sep. 30th, 2003 10:52 amГуляя по исходникам ядра Линукса в поисках информации о том, как в нём устроены 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;
Оператор условного выбора ?:, но без второго операнда. То есть вместо обычного, скажем,
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;