Jump to content

    

Косяк у Кейла

По вашему же примеру

if (fooType == FOO_TYPE_A || FOO_TYPE_B)

что хотел этой строкой сказать автор?

Не сочтите за труд прочитать пост автора полностью. Там черным по белому написано что хотел, но ошибся результате чего действительно получилась ГЛУПОСТЬ, но GCC компилятор ее пропустил в отличие от другого, котрому можно (и нужно) сказать, что if(1) и ему подобные, считать, если не ошибочными, то уж подозрительными ввиду бессмысленности анализа.

Написана глупость и плохо написана, но обсуждаем что компилятор пропустил ошибку. А может он за вас и программу должен написать? Советы давать где вы что не так закодили?

Все много проще - сообщать, что то, что ему подсунули являетя, или неоднозначным и он не может решить как поступить руководствуясь только иеющимся у него набором правил, или приводит, напротив, к однозначному результату и посему часть написанного будет просто им проигнорирована.

 

В данном случае вместо if (fooType == FOO_TYPE_A || FOO_TYPE_B) компилятор будет де-факто компилировать if(1) вопрос только в том, надо знать об этом программисту, или хрен с ним и пусть "знающий азы" разбирается уже с результатом, поскольку "просто ошибки не плодить" надо было. Типа сам дурак.

 

Мой ответ Вы знаете. А каков Ваш, если еще раз подумать?

Share this post


Link to post
Share on other sites
В данном случае вместо if (fooType == FOO_TYPE_A || FOO_TYPE_B) компилятор будет де-факто компилировать if(1)

С чего это?

Share this post


Link to post
Share on other sites
Это Вы себя пытаетесь убедить повторяя одно и то-же? Тогда можете продолжать.

Вам было указано на преднамеренное притягивание за уши цикла for к бесконечным. Вашим всевышним. Этот цикл конструктивно более сложносоставной и естественное его применение в проходе какой-то последовательности итераций. Для этого есть раздел инициализации. Безотносительно к стандарту Си, аналог цикла while наиболее естественнен для бесконечного цикла. То, что разработчики стандарта "заставили" компиляторы по-другому толковать управляющее условие for - на их совести. Подсказка константности условия выполнения цикла ещё более актуальна для for. Критика while попахивает лозунгом "как завещал великий Ленин".

Share this post


Link to post
Share on other sites

В защиту GCC - по умолчанию он молчалив, но Wall/Wextra никто не отменял.

В защиту K&R - если кому-то что-то не нравится, то это ваше дело, но правила есть правила, и библия K&R в первую очередь явилась фундаментом для стандарта ANSI C (C89). С тех пор многое поменялось в лице сахара, новых типов, макросов и т.д., но никак не фундаментальные вещи. Например, найдите отличия между главой 3.5 Циклы for и while и 6.8.5.3 The for statement C11 или между А 6.5. Арифметические преобразования и 6.3.1 Arithmetic operands С11. Пример про преобразование типов, что я приводил ранее, все же из ранних трудов и сейчас неактуален, т.к. в новом издании K&R ANSI преобразование звучит иначе (см. ссылку выше)

По поводу горячего спора for(;;){} vs while(1){} все точки над и уже расставлены, но for(;;) лег в основу FreeRTOS и ядра Linux.

Edited by Mihey_K

Share this post


Link to post
Share on other sites
С чего это?

А это пусть будет Вам "домашним заданием" :)

 

 

Share this post


Link to post
Share on other sites
Это Вы себя пытаетесь убедить повторяя одно и то-же?

Например код while (c = *ptr++) ... выдаёт варнинг в Кейле и ремарку в ИАРе. А это самый оптимизированный вариант вывода строки. Так что ругательство может указывать и на "высококачественные" участки кода. Типа "чувак, не гони так быстро" :)

 

В чём критерий качества?

Share this post


Link to post
Share on other sites
А это пусть будет Вам "домашним заданием" :)

if (fooType == FOO_TYPE_A || FOO_TYPE_B)

Пусть fooType не равно FOO_TYPE_A, а FOO_TYPE_B равно 0. И...?

 

К примеру, константы определены в виде перечисления:

typedef enum {

FOO_TYPE_B,

FOO_TYPE_A,

FOO_TYPE_ZLTIGO,

...

} FooType_t;

и в данный момент fooType == FOO_TYPE_ZLTIGO :rolleyes:

Share this post


Link to post
Share on other sites
А while ((c = *ptr++)) не будет.

Напоминает фичу разработчиков компилятора. Разве по стандарту это не одно и то же?

Share this post


Link to post
Share on other sites
Напоминает фичу разработчиков компилятора.
Возможно. Как и сами предупреждения с примечаниями. Это работает, грех не использовать.

Share this post


Link to post
Share on other sites
Возможно. Как и сами предупреждения с примечаниями.

Нет. Это абсолютно чистый, как слеза, Си обязательный к однозначному толкованию любым компилятором. Использовано правило по которому выражение с оператором присваивания заключенное в круглые скобки равно присваемому. Просто надо знать и понимать язык, тогда и мысли свои донести до компилятора можно четко не подавляя предупреждения, и не удивлясь тому, что они есть на разлюбезный, но неграмотный while(1).

Замечу, если кто не понимает, что наружные скобки это принадлежность оператора, а вот внутренние это они самые.

Share this post


Link to post
Share on other sites
По поводу горячего спора for(;;){} vs while(1){} все точки над и уже расставлены

If even a C beginner knows that for(;;) means an eternal loop, then who are you trying to make the code more readable for?

 

I guess that's what it all really boils down to. If you find yourself trying to make your source code readable for non-programmers, who don't even know the fundamental parts of the programming language, then you are only wasting time. They should not be reading your code.

 

And since everyone who should be reading your code already knows what for(;;) means, there is no point in making it further readable - it is already as readable as it gets.

Аргументация апостола.

 

There is one big, practical problem with this form, namely that compilers tend to give a warning for it: "condition is always true" or similar. That is a good warning, of a kind which you really don't want to disable, because it is useful for finding various bugs. For example a bug such as while(i = 1), when the programmer intended to write while(i == 1).

Только самый глупый компилятор не смог бы отличить было ли в выражении присваивание самой последней операцией.

+1 гвоздь.

 

Нет. Это абсолютно чистый, как слеза, Си обязательный к однозначному толкованию любым компилятором. Использовано правило по которому выражение с оператором присваивания заключенное в круглые скобки равно присваемому. Просто надо знать и понимать язык.

Замечу, если кто не понимает, что наружные скобки это принадлежность оператора, а вот внутренние это они самые.

То есть rvalue? А почему адрес (&) можно брать через скобки или кучу скобок?

Edited by GetSmart

Share this post


Link to post
Share on other sites
То есть rvalue?

Не понял столь лаконично заданного "вопроса". Насколько я мог догадаться, то да, присваивание вырабатывает значение (таков СТАНДАРТ) и по этой причне может применяться указанным образом.

А почему адрес (&) можно брать через скобки или кучу скобок?

Можете и здесь нарисовать кучу скобок, но достаточно ОДНОЙ пары.

 

Share this post


Link to post
Share on other sites

Значит, и на выражение while (c = 3) тоже будет предупреждение? А на while ((c = 3)) не будет?

Проверил - Кейл выдает и там и там, что, наверное, я хотел поставить ==.

Share this post


Link to post
Share on other sites
Значит, и на выражение while (c = 3) тоже будет предупреждение? А на while ((c = 3)) не будет?

По хорошему и там и там, но разные. В первом случае то, что получили, во втором, что константное. Тяжелый труд у писателей компиляторов, особенно, кода надо о непонятках сообщать.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this