Будет ли условное C всегда возвращать 1 или 0? - PullRequest
9 голосов
/ 20 августа 2010

Условные операторы C всегда возвращают [1 или 0] или они возвращают [0 или «что-то отличное от нуля»].Я спрашиваю, потому что:

псевдокод -

foo (адрес, следует отправить):
регистр >> = 1
регистр << = 1 // для сброса битв первой позиции <br>register | = shouldSend //, чтобы сигнализировать, следует ли отправлять или нет

проблема возникает, если кто-то передает в значение shouldSend значение true больше единицы (поскольку только 0 равно falseа все остальное верно, технически это верно).Так как я непосредственно ИЛИ указываю истинное значение shouldSend с регистром, лучше не говорить 0xFF!У меня уже есть решение, так что вопрос скорее для любопытства.Мне интересно, если:

foo (address, shouldSend):
регистр >> = 1
регистр << = 1 // для сброса бита в первой позиции <br>регистр| = (shouldSend> 0) // сигнализировать, следует ли отправлять или нет

решает проблему?я бы подумал, что теперь проблема передачи 0xFF (или вообще чего-то большего, чем 1) маскируется условным Си.но это только при условии, что условные выражения C гарантированно возвращают [0 или 1].

ps - я также понимаю, что это, вероятно, зависит от компилятора, но что говорит об этом стандарт ANSI?

Ответы [ 4 ]

17 голосов
/ 20 августа 2010

Стандарт указывает, что в результате всегда целочисленное значение равно 0 или 1

6.5.8 Реляционные операторы

Каждый из операторов <(меньшечем),> (больше чем), <= (меньше или равно) и> = (больше или равно) должны давать 1, если указанное отношение истинно, и 0, если оно ложно.92) Результат имеетвведите int.

1 голос
/ 20 августа 2010

Вместо того, чтобы смещаться вправо и снова смещаться влево назад, чтобы очистить LSB, я бы побитировал - и это с 0xFE:

register = register & 0xFE;

[править: предполагается, что регистр 8 бит. Если нет, при необходимости измените правый операнд]

Но да, если shouldSend является результатом условного теста, то по стандарту гарантируется, что он равен 0 или 1. Если есть какие-либо сомнения относительно того, можно ли генерировать shouldSend где-либо еще, было бы целесообразно добавить какая-то мера предосторожности у вас есть, или что-то вроде

register = register | (shouldSend ? 1 : 0);
1 голос
/ 20 августа 2010

Не имеет значения, указано это или нет. Лучше всегда проверять на ложность и четко указывать значения or-equals. Это устраняет любые опасения по поводу реализации компилятора и является более понятным и более понятным.

0 голосов
/ 20 августа 2010

Да. Это гарантировано в C99. У меня нет под рукой спецификации C89. Конечно, разработчики компиляторов иногда допускают ошибки, поэтому YMMV.

C99 определяет следующее в пункте 6 6.5.8 Операторы отношений :

Каждый из операторов <</strong> (меньше чем), > (больше чем), <= </strong> (меньше или равно) и > = (больше или равно) возвращает 1, если указанное отношение истинно, и 0, если оно ложно.

Те же или аналогичные пункты содержатся в пункте 3 6.5.9 Операторы равенства , в пункте 3 6.5.13 Логический оператор И и в пункте 3 6.5. 14 Оператор логического ИЛИ .

...