Столкнулся с такой интересной вещью: Почему если использовать эту конструкцию Код (Text): boolean a; if (a = true) { ..... ..... } компилятор не выдает ошибку?
Да извиняюсь, не проснулся. Точного ответа у меня нет, тут идет присвоение и конструкция в скобка будет равна true, только, что проверил. Код (Text): int led = 13; void setup() { pinMode(led, OUTPUT); digitalWrite(led, LOW); } void loop() { boolean a; if (a = true) { digitalWrite(led, HIGH); } }
да понятно, он делает свою работу, но почему не проверяет что в скобках нет операции сравнения? Если это проделать с int или с другим типом данных то он пишет ошибку конечно же))))))) БАГ?
Ради прикола, кинул в Студию и написал на C#, компилятор тоже не нашел ошибки. Тут увы не знаю, если студия не нашла ошибки, навряд ли это баг. UPD. Видимо придется с этим жить, вот что пишут http://arduino.cc/en/Reference/If С анг. у меня туго, вот перевод гугла
Здесь нет никакой ошибки, в C/C++ разрешено делать присваивание внутри условия. Чтобы не наступать на эти грабли с опечаткой "=" вместо "==", всегда ставьте константу первой в выражении, тогда компилятор будет на это ругаться.
Полагаю, речь идет об этом if (true = a) Код (Text): int led = 13; void setup() { pinMode(led, OUTPUT); digitalWrite(led, LOW); } void loop() { boolean a; if (true = a) { digitalWrite(led, HIGH); } } Но если работаете с переменными, есть шанс получить ошибку, пример от Tomasina, по моему мнению лучше.
Вывод - непонятная фича..... ВСЕМ СПАСИБО) хотя скорее всего это сделанно для гибкости языка программирования )))
Фитча на самом деле совершено понятная. При наличии списка равно-приоритетных операторов, выполнение их идет с права налево. Таким образом в вашем примере, сперва выполняется выражение присвоения, то есть переменной a присваивается значение true, после чего отрабатывает конструкция if. Именно подобная технология вообще дает возможность писать составные выражения. Компилятор её пропускает потому что это совершенно нормальная с точки зрения синтаксиса языка конструкция. По сути ваша запись эквивалентная такой: Код (Text): a = true; if ( a ) { // ... } Иногда можно встретить "обратный" вариант, как уже приводили пример выше, например такой: Код (Text): if ( 25 = a ) { // ... } Эта фитча основывается на том что все литералы в программе являются константой и компилятор узрит попытку изменить константу и выдаст ошибку на этапе компиляции. Такой стиль практиковался ранее, в настоящее же время если вы будите в компиляторе включать достаточно высокий уровень предупреждений, он вам выкинет предупреждение о том что у вас идет попытка присвоения в конструкции if, причем он программу скомпилирует но предупреждение покажет, ибо с точки зрения яыка это не ошибка. Инода человек пытается сократить код в ущерб читаемости влепливая в одну строчку все что влепить может, предупреждения компилятора отключает ибо мешают ему они а потом бац и фиг что работает. Включает предупреждения, а там ворох в котором он разобраться не может ибо пошел сознательно на составление выражений которые попадают под "подозрительные". Во многих книгах авторы советуют вовсе отказываться от операций присвоения в if, лишняя строка кода перед if сделает код только боле читаемым а объявление лишней переменной погоды не сделает, ибо компилятор при оптимизации может сам все что ему надо собрать в более короткий набор команд процессора не выделяя под эту переменную даже памяти в стеке. В целом на этой "непонятной фитче" собственно и стоит весь язык по сути, иначе бы у вас на одно действие была бы одна строчка кода, получилось бы что то типа Ассемблера И выглядело бы вот такое выражение: Код (Text): a = 3 + 5 + 2; Вот так : Код (Text): a = 3; a + 5; a + 2; P.s. С++ вообще язык дающий огромную свободу, но за эту свободу приходится платить тем что именно программист должен следить за тем что он делает, ибо коварный замысел программиста компилятору не известен и он говорит, ну ок видимо ты знаешь что делаешь .. флаг тебе в руки
Это не баг а фича. В языке программирования С всякое выражение присваивания возвращает значение, равное присваиваемому. А в условии оператора if можно ставить любое логическое или целочисленное выражение. Если результат 0, то условие ложно, если не 0 - истинно. Другой вопрос, что по хорошему компилятор должен выдавать предупреждение, что "что-то не так", но с точки зрения языка конструкция является синтаксически верной и осмысленной. Компиллятор, который используется Arduino IDE, кстати, ругается (выдает предупреждение): "warning: suggest parentheses around assignment used as truth value"