Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Косяк у Кейла
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2, 3, 4, 5, 6
aaarrr
Цитата(zltigo @ Aug 30 2015, 11:53) *
А вот такой случай из жизни (специально нашел в интернете, а не сочинил, дабы не выслушивать глупости про уши):
http://www.codeexplain.com/code/253778d0-3...c1-57064dc5a918

Это как раз случай вопиющей глупости. Что тут вообще можно комментировать? Компилятор не обязан быть нянькой для программиста, не понимающего азов.
zltigo
QUOTE (aaarrr @ Aug 30 2015, 13:29) *
Это как раз случай вопиющей глупости. Что тут вообще можно комментировать? Компилятор не обязан быть нянькой для программиста, не понимающего азов.

Если я, ну, например, пропущу где либо при правке "=" я тоже стану "програмистом не понимающим азов"? Да? В примере человек, зная, как правильно, тупо ошибся.
Так-что пожалуйста хватит о ЧУЖИХ глупостях, подумайте, пожалуй, о своих собственных "ушах".
aaarrr
Цитата(zltigo @ Aug 30 2015, 13:34) *
Если я, ну, например, пропущу где либо при правке "=" я тоже стану "програмистом не понимающим азов"? Да?

На то будет выдано совсем иного рода предупреждение, и Вы это прекрасно знаете.

Цитата(zltigo @ Aug 30 2015, 13:34) *
Так-что пожалуйста хватит о ЧУЖИХ глупостях, подумайте, пожалуй, о своих собственных "ушах".

Спасибо, пожалуй, действительно поберегу их от чужих КРИКОВ.
zltigo
QUOTE (aaarrr @ Aug 30 2015, 13:51) *
На то будет выдано совсем иного рода предупреждение, и Вы это прекрасно знаете.

Выдано? А зачем выдано? Может не надо его выдавать? Пусть программист "знающий азы" разбирается без "компилятора не обязаного быть нянькой для программиста".
Так-что уже действительно "поберегите себя" а то Вам тяжело раздваиваться.
Golikov A.
Вы пытаетесь поиск ошибок реализации дизайна возложить на компилятор. И это не правильно. Надо вырабатывать методологию создания кода, а не откручивать на максимум придирчивость компилятора. Надо не хорошо искать ошибки, а просто их не плодить...

По вашему же примеру
if (fooType == FOO_TYPE_A || FOO_TYPE_B)
что хотел этой строкой сказать автор? fooTpe равно А или В? тогда где скобки? Почему логический оператор? Написана глупость и плохо написана, но обсуждаем что компилятор пропустил ошибку. А может он за вас и программу должен написать? Советы давать где вы что не так закодили?







zltigo
QUOTE (Golikov A. @ Aug 30 2015, 14:01) *
По вашему же примеру
if (fooType == FOO_TYPE_A || FOO_TYPE_B)
что хотел этой строкой сказать автор?

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

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

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

Мой ответ Вы знаете. А каков Ваш, если еще раз подумать?
ViKo
Цитата(zltigo @ Aug 30 2015, 14:07) *
В данном случае вместо if (fooType == FOO_TYPE_A || FOO_TYPE_B) компилятор будет де-факто компилировать if(1)

С чего это?
GetSmart
Цитата(zltigo @ Aug 30 2015, 14:17) *
Это Вы себя пытаетесь убедить повторяя одно и то-же? Тогда можете продолжать.

Вам было указано на преднамеренное притягивание за уши цикла for к бесконечным. Вашим всевышним. Этот цикл конструктивно более сложносоставной и естественное его применение в проходе какой-то последовательности итераций. Для этого есть раздел инициализации. Безотносительно к стандарту Си, аналог цикла while наиболее естественнен для бесконечного цикла. То, что разработчики стандарта "заставили" компиляторы по-другому толковать управляющее условие for - на их совести. Подсказка константности условия выполнения цикла ещё более актуальна для for. Критика while попахивает лозунгом "как завещал великий Ленин".
Mihey_K
В защиту 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.
zltigo
QUOTE (ViKo @ Aug 30 2015, 15:25) *
С чего это?

А это пусть будет Вам "домашним заданием" sm.gif

GetSmart
Цитата(zltigo @ Aug 30 2015, 14:17) *
Это Вы себя пытаетесь убедить повторяя одно и то-же?

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

В чём критерий качества?
Сергей Борщ
Цитата(GetSmart @ Aug 30 2015, 20:03) *
Например код while (c = *ptr++) ... выдаёт варнинг в Кейле и ремарку в ИАРе.
А while ((c = *ptr++)) не будет.
ViKo
Цитата(zltigo @ Aug 30 2015, 19:53) *
А это пусть будет Вам "домашним заданием" sm.gif

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.gif
GetSmart
Цитата(Сергей Борщ @ Aug 30 2015, 21:46) *
А while ((c = *ptr++)) не будет.

Напоминает фичу разработчиков компилятора. Разве по стандарту это не одно и то же?
Сергей Борщ
Цитата(GetSmart @ Aug 31 2015, 12:08) *
Напоминает фичу разработчиков компилятора.
Возможно. Как и сами предупреждения с примечаниями. Это работает, грех не использовать.
zltigo
QUOTE (Сергей Борщ @ Aug 31 2015, 12:20) *
Возможно. Как и сами предупреждения с примечаниями.

Нет. Это абсолютно чистый, как слеза, Си обязательный к однозначному толкованию любым компилятором. Использовано правило по которому выражение с оператором присваивания заключенное в круглые скобки равно присваемому. Просто надо знать и понимать язык, тогда и мысли свои донести до компилятора можно четко не подавляя предупреждения, и не удивлясь тому, что они есть на разлюбезный, но неграмотный while(1).
Замечу, если кто не понимает, что наружные скобки это принадлежность оператора, а вот внутренние это они самые.
GetSmart
Цитата(Mihey_K @ Aug 30 2015, 20:21) *
По поводу горячего спора 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 гвоздь.

Цитата(zltigo @ Aug 31 2015, 14:15) *
Нет. Это абсолютно чистый, как слеза, Си обязательный к однозначному толкованию любым компилятором. Использовано правило по которому выражение с оператором присваивания заключенное в круглые скобки равно присваемому. Просто надо знать и понимать язык.
Замечу, если кто не понимает, что наружные скобки это принадлежность оператора, а вот внутренние это они самые.

То есть rvalue? А почему адрес (&) можно брать через скобки или кучу скобок?
zltigo
QUOTE (GetSmart @ Aug 31 2015, 13:49) *
То есть rvalue?

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

Можете и здесь нарисовать кучу скобок, но достаточно ОДНОЙ пары.
ViKo
Значит, и на выражение while (c = 3) тоже будет предупреждение? А на while ((c = 3)) не будет?
Проверил - Кейл выдает и там и там, что, наверное, я хотел поставить ==.
zltigo
QUOTE (ViKo @ Aug 31 2015, 14:22) *
Значит, и на выражение while (c = 3) тоже будет предупреждение? А на while ((c = 3)) не будет?

По хорошему и там и там, но разные. В первом случае то, что получили, во втором, что константное. Тяжелый труд у писателей компиляторов, особенно, кода надо о непонятках сообщать.
Сергей Борщ
Цитата(zltigo @ Aug 31 2015, 13:15) *
Это абсолютно чистый, как слеза, Си обязательный к однозначному толкованию любым компилятором. Использовано правило по которому выражение с оператором присваивания заключенное в круглые скобки равно присваемому.
В чистом, как слеза, Си, результатом оператора '=' является левый операнд, т.е. присваиваемое, вне зависимости от наличия скобок. А вот сама запись содержимого правого операнда в левый является побочным эффектом этого оператора. Это свойство позволяет писать a= b = c; И результат этого выражения будет идентичен выражению a = (b = c);, т.е. скобки здесь никакой синтаксической роли не играют.


Цитата(ViKo @ Aug 31 2015, 14:22) *
Проверил - Кейл выдает и там и там, что, наверное, я хотел поставить ==.
Сочувствую... gcc пишет так:
Код
./xxxx.cpp:125:16: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
     while( c = 3 )
                ^
Со скобками, соответственно, молчит. Ждите новую версию кейла.
GetSmart
Цитата(zltigo @ Aug 31 2015, 14:55) *
Не понял столь лаконично заданного "вопроса". Насколько я мог догадаться, то да, присваивание вырабатывает значение (таков СТАНДАРТ) и по этой причне может применяться указанным образом.

rvalue это результат [выражения]. lvalue это объект имеющий тип и адрес. Почему-то считается, что у него обязано быть имя. Но мне кажется безымянный lvalue легко создаётся в выражении: *(int *)Addr, где адрес - любое число, и тип тоже любой.

Если бы скобки приводили любое выражение к rvalue, то нельзя было бы брать адрес lvalue через скобки и на такое выражение (var) = value выдавалась бы ошибка. Значит скобки в выражении управляют только приоритетом вычисления операторов, при этом никакую информацию выражения не обрезают. Операция присваивания без помощи дополнительных скобок приводит выражение к типу rvalue. Причём к обрезанному или расширенному до ширины типа lvalue, в котором оно сохраняется. Приведите выдержки из стандарта, опровергающие такую логику работы скобок.

Если какой-то компилятор при этом перестаёт ругаться, то это его фича. В тексте ошибки компиляторов не содержится указание, что ошибка находится вне области скобок выражения, подразумевается вся область выражения.
Obam
Вирта на вас нет sm.gif "В чистом, как слеза, Си" sm.gif "Сколько чертей поместится на острие иглы" sm.gif
zltigo
QUOTE (Сергей Борщ @ Aug 31 2015, 15:39) *
В чистом, как слеза, Си, результатом оператора '=' является левый операнд, т.е. присваиваемое, вне зависимости от наличия скобок. А вот сама запись содержимого правого операнда в левый является побочным эффектом этого оператора. Это свойство позволяет писать a= b = c; И результат этого выражения будет идентичен выражению a = (b = c);, т.е. скобки здесь никакой синтаксической роли не играют.

писать "a = b = c" БЕЗ скобок вообще-то позволяет ПРАВИЛО ассоциативности, которое для '=' справа-налево, а не слева-направо, как для, например '=='.
Так-что о к чему все это было написано не пойму sad.gif.
Ну и кроме всего этого - а зачем ты пытаешься подменить этим a = b = c, выраженние, которое вообще-то a == b = c ?

Давай ты на пару с GetSmart , заглянешь хотя-бы в букварь K&R там прямо вариант while ((c = *ptr++)) рассматривается.

QUOTE
Сочувствую... gcc пишет так:
CODE
./xxxx.cpp:125:16: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
     while( c = 3 )
                ^
Со скобками, соответственно, молчит. Ждите новую версию кейла.

То есть все правильно - скобки отработали. Ну а на константное GCC традиционно не выдает предупреждений sad.gif. Можно смело писать багрепорт на Кейл sm.gif - называние темы таки ПРАВИЛЬНОЕ! sm.gif




QUOTE (GetSmart @ Aug 31 2015, 16:22) *
Если бы скобки приводили любое выражение

О любом речь не шла. Только в выражении содержащем оператор присваивания.
QUOTE
Если какой-то компилятор при этом перестаёт ругаться, то это его фича.

Вместо рассуждений, ну ознакомьтесь хоть с букварем от K&R такм Вам Автор языка покажет while ((c = *ptr++)) с "лишними" скобками.
GetSmart
Цитата(Сергей Борщ @ Aug 31 2015, 16:39) *
В чистом, как слеза, Си, результатом оператора '=' является левый операнд, т.е. присваиваемое, вне зависимости от наличия скобок. А вот сама запись содержимого правого операнда в левый является побочным эффектом этого оператора.

Не понял. Прямое действие оператора "=" в чём? Действие, не результат. Все операторы должны выполнять какое-то действие над операндами.

Цитата(zltigo @ Aug 31 2015, 18:12) *
О любом речь не шла. Только в выражении содержащем оператор присваивания.
...
Вместо рассуждений, ну ознакомьтесь хоть с букварем от K&R такм Вам Автор языка покажет while ((c = *ptr++)) с "лишними" скобками.

Логику озвучьте. Или выдержку из стандарта. Потому как нелогичен такой хак компиляторов. Что дают скобки выражению с оператором присваивания до сих пор не ясно. Сам оператор приводит всё выражение из левого и правого операндов присваивания к единому целому rvalue. Скобки тут ни причём.

Кстати, Кейл вполне умеет определять было ли присваивание последней операцией в while. Значит ругается на константу только по указке всевышнего. Пардон. Он не ругается.
zltigo
QUOTE (GetSmart @ Aug 31 2015, 17:41) *
Потому как нелогичен такой хак компиляторов.

Как прикольно получается - НЕпризнаение Вами "хаком" использования константы вместо условного выражения привело к "нелогичности" и требованию признать "хаком" while ((c = *ptr++)).
Хотя следует признать, что для однозначности все-же выражение while( x ) тоже по общему счету "хак" и при его запрете единственной формой стала-бы не вызывающая никаких толкований
while( (c = *ptr++) != '\0' ) и никаких вопросов по поводу наличия "лишних" () sm.gif.
Сергей Борщ
Цитата(zltigo @ Aug 31 2015, 17:12) *
писать "a = b = c" БЕЗ скобок вообще-то позволяет ПРАВИЛО ассоциативности, которое для '=' справа-налево, а не слева-направо, как для, например '=='.
Ну а чуть дальше развить мысль? Что результатом выражения b=c является rvalue, которое в свою очередь может быть вторым операндом оператора "a = ". И этот результат b=c является rvalue без скобок и от добавления скобок ни во что другое не превращается. Читаем еще раз:
Цитата(zltigo @ Aug 31 2015, 13:15) *
Использовано правило по которому выражение с оператором присваивания заключенное в круглые скобки равно присваемому.
Фантазии какие-то. То есть без скобок оно не будет равно присваиваемому? Оказывается - равно. Тогда при чем тут скобки? Или можно цитату из стандарта или хотя бы поминаемого всуе K&R про правило о заключении в скобки?
Цитата(GetSmart @ Aug 31 2015, 17:41) *
Не понял. Прямое действие оператора "=" в чём? Действие, не результат. Все операторы должны выполнять какое-то действие над операндами.
В чем прямое действие у оператора '+'? Какое действие он выполняет над операндами? Он возвращает их сумму. Аналогично оператор '=' возвращает значение своего левого операнда после присваивания:
Цитата
An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue.
GetSmart
Цитата(zltigo @ Aug 31 2015, 20:03) *
признать "хаком" while ((c = *ptr++))

Последняя выполненная операция от скобок не меняется. Тип выражения скобки не меняют, а его преобразование в логический тип происходит при встрече самых последних скобок, принадлежащих while. Если rvalue было логическим, то никаких преобразований не требуется. А т.к. логических типов и переменных в Си не существует, то после любого присваивания логического rvalue не будет точно, даже если было. И т.к. while (integer lvalue) и while (integer rvalue) не вызывает ругательств, то наличие присваивания тоже не должно, т.к. даёт такое же состояние - integer rvalue. Ругательство/предупреждение сделано в предположении того, что последнее присваивание есть опечатка. Если в стандарте чёрным по белому написано, что в местах анализа логических rvalue можно применять пару скобок для маскировки этого и только этого предупреждения, тогда всё безупречно. Но эта маскировка не должна происходить из каких-то других правил применения скобок.

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

Цитата(Сергей Борщ @ Aug 31 2015, 21:13) *
Аналогично оператор '=' возвращает значение своего левого операнда после присваивания:
Цитата
An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue.

Это прямое действие оператора - сохранение. А не побочное. И так же все преобразования rvalue в процессе этого. Например из логического в числовое представление. И "возвращает" неправильный перевод цитаты. Правильнее "выражение будет содержать" значение своего левого операнда после присваивания.
Golikov A.
Сдается мне основная ошибка беседующих это попытка покрыть варнинги стандартом. Стандарт покрывает только ошибки, да и то косвенно, в силу того что они не дают получить работающий бинарь.
Все варнинги это эвристика компиляторов для облегчения жизни. И авторы гцц решили что если в месте где обычно проверяют условие и может быть == встретиться = то надо человека предупредить, вдруг опечатался. И они же решили, что если человек поставив скобки дополнительные действие превращает в значение, то он знает что делает. Я так себе это вижу.
Таже фигня с ваел 1, если вы в себе не уверены, разрешите компилятору искать такие места, если знаете что делаете убирите разрешение. На то что он плохой или хороший это не влияет. Если он получает бинарь - молодец, нет - не молодец. А прочее это удобство бонусом. По стандарту что делать и как интерпретировать такие выражение описано, и всех делов имхо!
zltigo
QUOTE (Сергей Борщ @ Aug 31 2015, 20:13) *
Фантазии какие-то. То есть без скобок оно не будет равно присваиваемому? Оказывается - равно. Тогда при чем тут скобки?

В приведеном тобой примере НЕ имеющим отношения к обсуждаемому наличие скобок ничего не меняет по причине действия названного мой другого правила.
Но это совершенно не означает, что наличие заключающих скобок для выражения присваивания никогда ничего не меняет.
Что не понятно-то?
QUOTE
Или можно цитату из стандарта или хотя бы поминаемого всуе K&R про правило о заключении в скобки?

Ты откуда взял это выражение с двойными скобками? Я лет 30 назад из K&R - просто другого не было ничего sm.gif и с ТЕХ ПОР ТАК ПИШУ. Сейчас скачал 3 издание, там на вскидку попытался найти но все уже какое-то причесанное под учебник с явными операторами сравнения.



QUOTE (Golikov A. @ Aug 31 2015, 21:31) *
Таже фигня с ваел 1, если вы в себе не уверены

Не надо нести глупости про "неувереность в себе", с ТУПЫМ упрямством сводить все к вырожденному варианту выражения и после чего "удивляться", ну только последний дурак может такую ошибку сделать. Я приводил примеры, в том числе и специально чужой из жизни, когда безмолвное разрешение компилятором абсолютно ни для чего ненужного трюка while( CONST ) приводит к пропуску ошибки. Все, достаточно объяснений - имеющий разум да поймет.
Golikov A.
Имеющий то уже давно понял.
Вы опять потеряли фокус. Стандарт описывает как из слов получить бинарь. Компилятор делает это по описанному стандартом методу. Все остальное это упражнения для ума. В этом контексте нет разрешений и запретов, есть просто перевод текста в бинарь, алгоритма в программу, по заданным правилам и все...
zltigo
QUOTE (Golikov A. @ Sep 1 2015, 06:12) *
Вы опять потеряли фокус. Стандарт описывает как из слов получить бинарь. Компилятор делает это по описанному стандартом методу. Все остальное это упражнения для ума. В этом контексте нет разрешений и запретов, есть просто перевод текста в бинарь, алгоритма в программу, по заданным правилам и все...

Нет далеко совсем не все. Этот "перевод" должен быть максимально эффективным и безошибочными. Для этого и надо заниматься и "упражнениями для ума" и добиваться максимального взаимопонимания с компилятором. В противном случае легко и просто получается говнокод, он-же индийский,... - работает как-то иногда и ладно, а что не заработает полезем отладчиком и залатаем. Ну как-же говнокодеру без отладчика, ведь он не знает четко, как им написанное "в бинарь, алгоритма в программу" перевратится и как будет работать. А тут еще некоторые компиляторы всякие предупреждения выдают - у него уже "все работает", и вообще он этот кусок у другого говнокодера из интнеренту взял, а компилятор чего-то там пишет. "Плохой" этот компилятор - нет что-бы просто "перевести в бинарь".

А вообще хотелось-бы напомнить с чего все это c while(CONST) началось: http://electronix.ru/forum/index.php?showt...t&p=1361143
Это совершенно бездумный "совет" в котром не только была НЕВЕРНО названа причина использования такого трюка, но и призвано тупо повторять трюк "автоматически" ( автору предлагаю
переписать "правильно" ну хотя-бы банальный макрос MIN( x, y )
CODE
#define MIN( X, Y )           \
( {                                  \
   typeof (X) xx = (X);       \
   typeof (Y) yy = (Y);        \
   (xx < yy) ? xx : yy;        \
} )


)
Только ведь сей "совет" никого не покоробил, зато ответ, в котором выражение do{...}while(0) было названо трюком, коим оно и является, вызвало бурную реакцию.

Не удержался sad.gif. Ладно, теперь уж точно все!
Kabdim
Цитата(zltigo @ Sep 1 2015, 08:44) *
А вообще хотелось-бы напомнить с чего все это c while(CONST) началось: http://electronix.ru/forum/index.php?showt...t&p=1361143
Это совершенно бездумный "совет" в котром не только была НЕВЕРНО названа причина использования такого трюка, но и призвано тупо повторять трюк "автоматически" (

Ну так я не против того что несколькострочный макрос это формально неверный признак и так бысло сказано из расчёта на нормальный стиль форматирования, на то что макрос содержит команды, а не строковые литералы и т.д. Вобщем в расчёте на то что читающий имеет желание понимать сказанное. В остальном я не услышал от вас ни доказателств того что это неверно, ни ответов на другие вопросы. И должен заметить я с улыбкой читаю этот топик и всё жду когда же вы начнете отвечать на вопросы вам заданные. biggrin.gif
GetSmart
Цитата(zltigo @ Sep 1 2015, 00:49) *
Что не понятно-то?

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

Тавтология. Отсебятина или из стандарта?

Даже больше. Здесь не только зацитировано X==X, но и показано, что наличие скобок в данном примере ничего не меняет. Именно такой смысл у формулировки. Спец по бессмысленности always true должен такую ерунду чуять за версту.

Добавление чего-то должно формулироваться в указании отличия. Например, добавление скобок меняет последовательность вычислений операторов. А в данном случае отличие - подтверждение отсутствия опечатки. Что-то мешает внятно писать?
Petka
Цитата(zltigo @ Aug 31 2015, 23:49) *
...
Ты откуда взял это выражение с двойными скобками? Я лет 30 назад из K&R - просто другого не было ничего sm.gif и с ТЕХ ПОР ТАК ПИШУ. Сейчас скачал 3 издание, там на вскидку попытался найти но все уже какое-то причесанное под учебник с явными операторами сравнения.
...

Тут такое дело...
Код от "Самого" Ритчи: https://github.com/mortdeus/legacy-cc/blob/...120c/c11.c#L219
И не надо фантазировать на пустом месте по поводу скобок.

P.S. Так я от Вас и не получил подтверждения Ваших слов про:
"...ибо while(константа) принципиально ошибочное выражение,..."
Получил только очередные фантазии про цикл for(;;), которого ВООБЩЕ не было в первых компилаторах Си. А while был. И автор языка для циклов использовал именно while.
GetSmart
На тему нововведений хочется прояснить ещё один любопытный нюанс. В интернете написано, что до стандарта 89 года пустой список аргументов функций объявлялся пустыми скобками. Что и естественно, и просто в реализации компилятора. Т.к. встреча ключевого слова void (без описываемого нововведения) обозначает объявление типа. Внутри же списка аргументов из-за void появляется некоторая нестыковка. В чём был смысл нововведения? Может есть некие аналогии или другие принципы? Или боязнь пустых скобок. Хотя в for() их таки притянули за уши. Может кто-то интересовался историей эволюции или читал что-то похожее на мемуары.
den_po
Цитата(GetSmart @ Oct 8 2015, 14:55) *
На тему нововведений хочется прояснить ещё один любопытный нюанс. В интернете написано, что до стандарта 89 года пустой список аргументов функций объявлялся пустыми скобками.

А что стали обозначать пустые скобки со стандарта 89 года, там написано?
GetSmart
Думаю, zltigo сказал бы: "бессмысленность".

Компиляторы, по желанию своих разработчиков, могут выдать "deprecated".

----

Может быть мой вопрос как-то пересекается с прототипированием функций. В каких-то источниках акцентируются прототипы. Но ясная причина отказа от пустых скобок не обозначена.
Golikov A.
думаю дань всяким чекерам, чтобы явно указать что вы не забыли параметры, а их реально не должно быть. Или чтобы отличать вызов функции от ее объявления более наглядно.... или чтобы разработчик мог явно указать что точно ничего вызывать не надо, а он ничего не забыл... резюме - для повышения читаемости и понятности кода...
GetSmart
Цитата(den_po @ Oct 8 2015, 17:31) *
А что стали обозначать пустые скобки со стандарта 89 года, там написано?

Видимо некорректно и неточно написал, скопипастив источник интернета. Void навязывается только в прототипах функций. Но из-за этого он допускается и во всех остальных местах объявления заголовков функций. И эта полумера/полутребование кривое вдвойне. Либо что-то важное ещё не озвучено.


Golikov A.
Невозможно забыть/опечататься в определении функции с её телом, а так же при её вызове, т.к. у компилятора есть вся информация для выявления ошибки. В прототипе тоже сомнительно.
zltigo
QUOTE (GetSmart @ Oct 10 2015, 08:46) *
Невозможно забыть/опечататься в определении функции с её телом,

Это Вы за себя говорите, или за всяких "кодеров" (не понимаюших правил хрошего тона в языке но наплодивших и продлжкющих плодить всякое) тоже?

Вот что это:

smart();

1) Вызов функции;
2) Опредеоение функции;
3) Макрос;

QUOTE
а так же при её вызове, т.к. у компилятора есть вся информация для выявления ошибки.

Нету. Как Вы не можете без void отличить быдлокодеровское определение функции с возвращаемым int от вызова функции, так и компилятор этого не может.
Посему ныне требуемое определение функции:
void function(void);
вполне логично,
void function();
нелогично, а
function();
использовать нельзя, по тому, что это на самом деле, благодаря sad.gif изначально заложенной глупости, совсем другая функция:
int function(void);
зато, блин, оталась возможноcть писать:
function(void);

Проблема в том, что изменения ( изменения, а не дополнения ) в стандарте страдают полумерами sad.gif - вводя тот-же void, надо было запрешать и по умолчанию возвращаемое int. Но ведь сколько "кодеров" такое УЖЕ размножили в мириадах строк, как и дикое while(1) sad.gif. Вот и тянут sad.gif sad.gif sad.gif
ViKo
В С99 неявный возвращаемый int убрали. А вы все старье обсуждаете.
den_po
Цитата(zltigo @ Oct 10 2015, 10:59) *
нелогично, а
function();
использовать нельзя, по тому, что это на самом деле, благодаря sad.gif изначально заложенной глупости, совсем другая функция:
int function(void);

int function();
и
int function(void);
это в си совсем не одно и то же
zltigo
QUOTE (den_po @ Oct 10 2015, 10:50) *
int function();
и
int function(void);
это в си совсем не одно и то же

Да ну! Не дайте помереть невежей - поведайте в чем-же это было раньше отличие.

QUOTE (ViKo @ Oct 10 2015, 10:09) *
В С99 неявный возвращаемый int убрали. А вы все старье обсуждаете.

Убрали убрали так, что какой-нибудь GCC максимум предупреждение выдает, да и то подавлнное.
den_po
Цитата(zltigo @ Oct 10 2015, 19:12) *
Да ну! Не дайте помереть невежей - поведайте в чем-же это было раньше отличие.

Отличие и сейчас есть. Первый вариант позволяет вызвать функцию с любым числом аргументов.
GetSmart
Цитата(den_po @ Oct 10 2015, 19:40) *
Отличие и сейчас есть. Первый вариант позволяет вызвать функцию с любым числом аргументов.

В какого года стандарте это определено?

int function();
На этот вариант 4-ый Кейл выдаёт варнинг - "deprecated". Ругается даже на static-прототип без void в пустом списке аргументов.

zltigo
void в месте возвращаемого функцией значения к делу отношения не имеет. Там void ни с чем не конфликтует. Странно только, что неявным там был int, а не отсутствие возвращаемого значения (aka void в будущем).
zltigo
QUOTE (den_po @ Oct 10 2015, 18:40) *
Первый вариант позволяет вызвать функцию с любым числом аргументов.

Разумеется нет. И вообще "любое" в Cи вообще не сущесвует, ибо даже funсtion(...); , если компилятор и не выдаст ошибку, как минимум бессмысленна, посему - funсtion( param, .... );
То есть не менее одного.




QUOTE (GetSmart @ Oct 10 2015, 19:20) *
void в месте возвращаемого функцией значения к делу отношения не имеет.

Имеет, как пример полностью однозначного определения функции и когда убрали разрешенную неопределенность с возвращаемым значением, стало логичным убрать ее и в передаваемым значением.
den_po
Цитата(GetSmart @ Oct 10 2015, 20:20) *
В какого года стандарте это определено?

С того же 89 оно упоминается. Тогда оно было "устаревающим", сейчас устаревшее, но из стандарта не удалённое.

Цитата(zltigo @ Oct 10 2015, 21:08) *
Разумеется нет. И вообще "любое" в Cи вообще не сущесвует, ибо даже funktion(...); , если компилятор и не выдаст ошибку, как минимум бессмысленна, посему - funktion( param, .... );
То есть не менее одного.

Гуглите, читайте, пробуйте.
zltigo
QUOTE (den_po @ Oct 10 2015, 22:26) *
Гуглите, читайте, пробуйте.

Понятно. Просто сбрехали.
den_po
Цитата(zltigo @ Oct 11 2015, 00:18) *
Понятно. Просто сбрехали.

Вы из тех, кто считает себя слишком опытным, чтоб допустить свою неправоту, да?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.