Сергей Борщ 134 31 августа, 2015 Опубликовано 31 августа, 2015 · Жалоба Это абсолютно чистый, как слеза, Си обязательный к однозначному толкованию любым компилятором. Использовано правило по которому выражение с оператором присваивания заключенное в круглые скобки равно присваемому.В чистом, как слеза, Си, результатом оператора '=' является левый операнд, т.е. присваиваемое, вне зависимости от наличия скобок. А вот сама запись содержимого правого операнда в левый является побочным эффектом этого оператора. Это свойство позволяет писать a= b = c; И результат этого выражения будет идентичен выражению a = (b = c);, т.е. скобки здесь никакой синтаксической роли не играют. Проверил - Кейл выдает и там и там, что, наверное, я хотел поставить ==.Сочувствую... gcc пишет так: ./xxxx.cpp:125:16: warning: suggest parentheses around assignment used as truth value [-Wparentheses] while( c = 3 ) ^ Со скобками, соответственно, молчит. Ждите новую версию кейла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 31 августа, 2015 Опубликовано 31 августа, 2015 (изменено) · Жалоба Не понял столь лаконично заданного "вопроса". Насколько я мог догадаться, то да, присваивание вырабатывает значение (таков СТАНДАРТ) и по этой причне может применяться указанным образом. rvalue это результат [выражения]. lvalue это объект имеющий тип и адрес. Почему-то считается, что у него обязано быть имя. Но мне кажется безымянный lvalue легко создаётся в выражении: *(int *)Addr, где адрес - любое число, и тип тоже любой. Если бы скобки приводили любое выражение к rvalue, то нельзя было бы брать адрес lvalue через скобки и на такое выражение (var) = value выдавалась бы ошибка. Значит скобки в выражении управляют только приоритетом вычисления операторов, при этом никакую информацию выражения не обрезают. Операция присваивания без помощи дополнительных скобок приводит выражение к типу rvalue. Причём к обрезанному или расширенному до ширины типа lvalue, в котором оно сохраняется. Приведите выдержки из стандарта, опровергающие такую логику работы скобок. Если какой-то компилятор при этом перестаёт ругаться, то это его фича. В тексте ошибки компиляторов не содержится указание, что ошибка находится вне области скобок выражения, подразумевается вся область выражения. Изменено 31 августа, 2015 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 37 31 августа, 2015 Опубликовано 31 августа, 2015 · Жалоба Вирта на вас нет :) "В чистом, как слеза, Си" :) "Сколько чертей поместится на острие иглы" :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 31 августа, 2015 Опубликовано 31 августа, 2015 · Жалоба В чистом, как слеза, Си, результатом оператора '=' является левый операнд, т.е. присваиваемое, вне зависимости от наличия скобок. А вот сама запись содержимого правого операнда в левый является побочным эффектом этого оператора. Это свойство позволяет писать a= b = c; И результат этого выражения будет идентичен выражению a = (b = c);, т.е. скобки здесь никакой синтаксической роли не играют. писать "a = b = c" БЕЗ скобок вообще-то позволяет ПРАВИЛО ассоциативности, которое для '=' справа-налево, а не слева-направо, как для, например '=='. Так-что о к чему все это было написано не пойму :(. Ну и кроме всего этого - а зачем ты пытаешься подменить этим a = b = c, выраженние, которое вообще-то a == b = c ? Давай ты на пару с GetSmart , заглянешь хотя-бы в букварь K&R там прямо вариант while ((c = *ptr++)) рассматривается. Сочувствую... gcc пишет так: ./xxxx.cpp:125:16: warning: suggest parentheses around assignment used as truth value [-Wparentheses] while( c = 3 ) ^ Со скобками, соответственно, молчит. Ждите новую версию кейла. То есть все правильно - скобки отработали. Ну а на константное GCC традиционно не выдает предупреждений :(. Можно смело писать багрепорт на Кейл :) - называние темы таки ПРАВИЛЬНОЕ! :) Если бы скобки приводили любое выражение О любом речь не шла. Только в выражении содержащем оператор присваивания. Если какой-то компилятор при этом перестаёт ругаться, то это его фича. Вместо рассуждений, ну ознакомьтесь хоть с букварем от K&R такм Вам Автор языка покажет while ((c = *ptr++)) с "лишними" скобками. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 31 августа, 2015 Опубликовано 31 августа, 2015 (изменено) · Жалоба В чистом, как слеза, Си, результатом оператора '=' является левый операнд, т.е. присваиваемое, вне зависимости от наличия скобок. А вот сама запись содержимого правого операнда в левый является побочным эффектом этого оператора. Не понял. Прямое действие оператора "=" в чём? Действие, не результат. Все операторы должны выполнять какое-то действие над операндами. О любом речь не шла. Только в выражении содержащем оператор присваивания. ... Вместо рассуждений, ну ознакомьтесь хоть с букварем от K&R такм Вам Автор языка покажет while ((c = *ptr++)) с "лишними" скобками. Логику озвучьте. Или выдержку из стандарта. Потому как нелогичен такой хак компиляторов. Что дают скобки выражению с оператором присваивания до сих пор не ясно. Сам оператор приводит всё выражение из левого и правого операндов присваивания к единому целому rvalue. Скобки тут ни причём. Кстати, Кейл вполне умеет определять было ли присваивание последней операцией в while. Значит ругается на константу только по указке всевышнего. Пардон. Он не ругается. Изменено 31 августа, 2015 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 31 августа, 2015 Опубликовано 31 августа, 2015 · Жалоба Потому как нелогичен такой хак компиляторов. Как прикольно получается - НЕпризнаение Вами "хаком" использования константы вместо условного выражения привело к "нелогичности" и требованию признать "хаком" while ((c = *ptr++)). Хотя следует признать, что для однозначности все-же выражение while( x ) тоже по общему счету "хак" и при его запрете единственной формой стала-бы не вызывающая никаких толкований while( (c = *ptr++) != '\0' ) и никаких вопросов по поводу наличия "лишних" () :). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 31 августа, 2015 Опубликовано 31 августа, 2015 · Жалоба писать "a = b = c" БЕЗ скобок вообще-то позволяет ПРАВИЛО ассоциативности, которое для '=' справа-налево, а не слева-направо, как для, например '=='.Ну а чуть дальше развить мысль? Что результатом выражения b=c является rvalue, которое в свою очередь может быть вторым операндом оператора "a = ". И этот результат b=c является rvalue без скобок и от добавления скобок ни во что другое не превращается. Читаем еще раз: Использовано правило по которому выражение с оператором присваивания заключенное в круглые скобки равно присваемому.Фантазии какие-то. То есть без скобок оно не будет равно присваиваемому? Оказывается - равно. Тогда при чем тут скобки? Или можно цитату из стандарта или хотя бы поминаемого всуе K&R про правило о заключении в скобки? Не понял. Прямое действие оператора "=" в чём? Действие, не результат. Все операторы должны выполнять какое-то действие над операндами.В чем прямое действие у оператора '+'? Какое действие он выполняет над операндами? Он возвращает их сумму. Аналогично оператор '=' возвращает значение своего левого операнда после присваивания: 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 0 31 августа, 2015 Опубликовано 31 августа, 2015 (изменено) · Жалоба признать "хаком" while ((c = *ptr++)) Последняя выполненная операция от скобок не меняется. Тип выражения скобки не меняют, а его преобразование в логический тип происходит при встрече самых последних скобок, принадлежащих while. Если rvalue было логическим, то никаких преобразований не требуется. А т.к. логических типов и переменных в Си не существует, то после любого присваивания логического rvalue не будет точно, даже если было. И т.к. while (integer lvalue) и while (integer rvalue) не вызывает ругательств, то наличие присваивания тоже не должно, т.к. даёт такое же состояние - integer rvalue. Ругательство/предупреждение сделано в предположении того, что последнее присваивание есть опечатка. Если в стандарте чёрным по белому написано, что в местах анализа логических rvalue можно применять пару скобок для маскировки этого и только этого предупреждения, тогда всё безупречно. Но эта маскировка не должна происходить из каких-то других правил применения скобок. По поводу константы в условных выражениях цикла стоит закрыть тему. Тухлые помидоры предлагайте в другом месте. Аналогично оператор '=' возвращает значение своего левого операнда после присваивания: 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 в процессе этого. Например из логического в числовое представление. И "возвращает" неправильный перевод цитаты. Правильнее "выражение будет содержать" значение своего левого операнда после присваивания. Изменено 1 сентября, 2015 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 31 августа, 2015 Опубликовано 31 августа, 2015 · Жалоба Сдается мне основная ошибка беседующих это попытка покрыть варнинги стандартом. Стандарт покрывает только ошибки, да и то косвенно, в силу того что они не дают получить работающий бинарь. Все варнинги это эвристика компиляторов для облегчения жизни. И авторы гцц решили что если в месте где обычно проверяют условие и может быть == встретиться = то надо человека предупредить, вдруг опечатался. И они же решили, что если человек поставив скобки дополнительные действие превращает в значение, то он знает что делает. Я так себе это вижу. Таже фигня с ваел 1, если вы в себе не уверены, разрешите компилятору искать такие места, если знаете что делаете убирите разрешение. На то что он плохой или хороший это не влияет. Если он получает бинарь - молодец, нет - не молодец. А прочее это удобство бонусом. По стандарту что делать и как интерпретировать такие выражение описано, и всех делов имхо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 31 августа, 2015 Опубликовано 31 августа, 2015 · Жалоба Фантазии какие-то. То есть без скобок оно не будет равно присваиваемому? Оказывается - равно. Тогда при чем тут скобки? В приведеном тобой примере НЕ имеющим отношения к обсуждаемому наличие скобок ничего не меняет по причине действия названного мой другого правила. Но это совершенно не означает, что наличие заключающих скобок для выражения присваивания никогда ничего не меняет. Что не понятно-то? Или можно цитату из стандарта или хотя бы поминаемого всуе K&R про правило о заключении в скобки? Ты откуда взял это выражение с двойными скобками? Я лет 30 назад из K&R - просто другого не было ничего :) и с ТЕХ ПОР ТАК ПИШУ. Сейчас скачал 3 издание, там на вскидку попытался найти но все уже какое-то причесанное под учебник с явными операторами сравнения. Таже фигня с ваел 1, если вы в себе не уверены Не надо нести глупости про "неувереность в себе", с ТУПЫМ упрямством сводить все к вырожденному варианту выражения и после чего "удивляться", ну только последний дурак может такую ошибку сделать. Я приводил примеры, в том числе и специально чужой из жизни, когда безмолвное разрешение компилятором абсолютно ни для чего ненужного трюка while( CONST ) приводит к пропуску ошибки. Все, достаточно объяснений - имеющий разум да поймет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 1 сентября, 2015 Опубликовано 1 сентября, 2015 · Жалоба Имеющий то уже давно понял. Вы опять потеряли фокус. Стандарт описывает как из слов получить бинарь. Компилятор делает это по описанному стандартом методу. Все остальное это упражнения для ума. В этом контексте нет разрешений и запретов, есть просто перевод текста в бинарь, алгоритма в программу, по заданным правилам и все... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 1 сентября, 2015 Опубликовано 1 сентября, 2015 · Жалоба Вы опять потеряли фокус. Стандарт описывает как из слов получить бинарь. Компилятор делает это по описанному стандартом методу. Все остальное это упражнения для ума. В этом контексте нет разрешений и запретов, есть просто перевод текста в бинарь, алгоритма в программу, по заданным правилам и все... Нет далеко совсем не все. Этот "перевод" должен быть максимально эффективным и безошибочными. Для этого и надо заниматься и "упражнениями для ума" и добиваться максимального взаимопонимания с компилятором. В противном случае легко и просто получается говнокод, он-же индийский,... - работает как-то иногда и ладно, а что не заработает полезем отладчиком и залатаем. Ну как-же говнокодеру без отладчика, ведь он не знает четко, как им написанное "в бинарь, алгоритма в программу" перевратится и как будет работать. А тут еще некоторые компиляторы всякие предупреждения выдают - у него уже "все работает", и вообще он этот кусок у другого говнокодера из интнеренту взял, а компилятор чего-то там пишет. "Плохой" этот компилятор - нет что-бы просто "перевести в бинарь". А вообще хотелось-бы напомнить с чего все это c while(CONST) началось: http://electronix.ru/forum/index.php?showt...t&p=1361143 Это совершенно бездумный "совет" в котром не только была НЕВЕРНО названа причина использования такого трюка, но и призвано тупо повторять трюк "автоматически" ( автору предлагаю переписать "правильно" ну хотя-бы банальный макрос MIN( x, y ) #define MIN( X, Y ) \ ( { \ typeof (X) xx = (X); \ typeof (Y) yy = (Y); \ (xx < yy) ? xx : yy; \ } ) ) Только ведь сей "совет" никого не покоробил, зато ответ, в котором выражение do{...}while(0) было названо трюком, коим оно и является, вызвало бурную реакцию. Не удержался :(. Ладно, теперь уж точно все! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 1 сентября, 2015 Опубликовано 1 сентября, 2015 (изменено) · Жалоба А вообще хотелось-бы напомнить с чего все это c while(CONST) началось: http://electronix.ru/forum/index.php?showt...t&p=1361143 Это совершенно бездумный "совет" в котром не только была НЕВЕРНО названа причина использования такого трюка, но и призвано тупо повторять трюк "автоматически" ( Ну так я не против того что несколькострочный макрос это формально неверный признак и так бысло сказано из расчёта на нормальный стиль форматирования, на то что макрос содержит команды, а не строковые литералы и т.д. Вобщем в расчёте на то что читающий имеет желание понимать сказанное. В остальном я не услышал от вас ни доказателств того что это неверно, ни ответов на другие вопросы. И должен заметить я с улыбкой читаю этот топик и всё жду когда же вы начнете отвечать на вопросы вам заданные. Изменено 1 сентября, 2015 пользователем Kabdim Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 1 сентября, 2015 Опубликовано 1 сентября, 2015 (изменено) · Жалоба Что не понятно-то? Использовано правило по которому выражение с оператором присваивания заключенное в круглые скобки равно присваемому. Просто надо знать и понимать язык. Тавтология. Отсебятина или из стандарта? Даже больше. Здесь не только зацитировано X==X, но и показано, что наличие скобок в данном примере ничего не меняет. Именно такой смысл у формулировки. Спец по бессмысленности always true должен такую ерунду чуять за версту. Добавление чего-то должно формулироваться в указании отличия. Например, добавление скобок меняет последовательность вычислений операторов. А в данном случае отличие - подтверждение отсутствия опечатки. Что-то мешает внятно писать? Изменено 2 сентября, 2015 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 2 сентября, 2015 Опубликовано 2 сентября, 2015 · Жалоба ... Ты откуда взял это выражение с двойными скобками? Я лет 30 назад из K&R - просто другого не было ничего :) и с ТЕХ ПОР ТАК ПИШУ. Сейчас скачал 3 издание, там на вскидку попытался найти но все уже какое-то причесанное под учебник с явными операторами сравнения. ... Тут такое дело... Код от "Самого" Ритчи: https://github.com/mortdeus/legacy-cc/blob/...120c/c11.c#L219 И не надо фантазировать на пустом месте по поводу скобок. P.S. Так я от Вас и не получил подтверждения Ваших слов про: "...ибо while(константа) принципиально ошибочное выражение,..." Получил только очередные фантазии про цикл for(;;), которого ВООБЩЕ не было в первых компилаторах Си. А while был. И автор языка для циклов использовал именно while. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться