реклама на сайте
подробности

 
 
> Косяк у Кейла, Препроцессор не следит за скобками
ViKo
сообщение Aug 28 2015, 11:21
Сообщение #1


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Делаю функцию программной задержки. (Длинная не нужна, естественно, но вопрос уже академический, захотел дойти до предела.) Каждый цикл выполняется за 4 такта, отсюда и деление на 4000. Нюансы не интересны, не в этом дело.

Код
#define SYSCLK        48000000ULL
#define _NS    1
#define _US    1000
#define _MS    1000000
#define _SS    1000000000

#define DELAY(VALUE, UNIT);    \
  /* DelayFourCycles(VALUE * UNIT * (SYSCLK / 1000000) / 4000); */ \
  DelayFourCycles((SYSCLK / 1000000) * VALUE * UNIT / 4000);

  DELAY(50, _SS);


Так вот, когда сделал, как в закомментированной строке, Кейл ругается на то, что число не влазит в int. И загружает в функцию абы что. Если же сделать, как в строке без комментария, то все вычисляется правильно. Выходит, Кейл видит что последовательность операций равнозначна, что со скобками, что без, и лихо их отбрасывает. Возникает переполнение. Хотя не понятно, отчего возникает, 64 битов должно хватать (на компьютерном калькуляторе хватает). Как будто у Кейла не 64-битовое вычисление, а меньшее.
Go to the top of the page
 
+Quote Post
18 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 99)
aaarrr
сообщение Aug 28 2015, 11:44
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



В макросе не хватает скобок для VALUE и UNIT.
Go to the top of the page
 
+Quote Post
den_po
сообщение Aug 28 2015, 11:51
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 139
Регистрация: 9-11-12
Из: Санкт-Петербург
Пользователь №: 74 315



Цитата(ViKo @ Aug 28 2015, 16:21) *
Как будто у Кейла не 64-битовое вычисление, а меньшее.

а если DELAY(50ULL, _SS); ?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 28 2015, 12:00
Сообщение #4


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Заменил
#define _NS 1ULL
#define _US 1000ULL
#define _MS 1000000ULL
#define _SS 1000000000ULL
Вычисляется правильно. Т.е., пока препроцессор не увидит число ULL, он вычисляет в 32 разрядах.
Со скобками, похоже, я подметил правильно. Он их игнорирует, если может себе позволить.

Цитата(den_po @ Aug 28 2015, 14:51) *
а если DELAY(50ULL, _SS); ?

Тоже работает.

Цитата(aaarrr @ Aug 28 2015, 14:44) *
В макросе не хватает скобок для VALUE и UNIT.

"Не помогает".
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Aug 28 2015, 12:01
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Кмк объяснение другое.
VALUE * UNIT * (SYSCLK / 1000000) / 4000
1 действие - (SYSCLK / 1000000) ок
VALUE * UNIT * temp64_1 / 4000
2 действие:
Операции выплняются по очереди, т.е. умножение двух int друг на друга и т.к. они оба int то никакого неявного расширяющего преобразования не происходит. Т.к. это явные константы, то перемножение выолняет компилятор и закономерно ругается. Были бы это переменные тихо бы переполнялось в рантайме.
Правило хорошего тона расширять явно первое значение до желаемого типа.
ЗЫ Это поведение, не Кейла, а любимого C.

Сообщение отредактировал Kabdim - Aug 28 2015, 12:02
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 28 2015, 12:04
Сообщение #6


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Kabdim @ Aug 28 2015, 15:01) *
Кмк объяснение другое.
...
Операции выплняются по очереди, т.е. умножение двух int друг на друга и т.к. они оба int то никакого неявного расширяющего преобразования не происходит.

Понял. Спасибо!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 28 2015, 12:08
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ViKo @ Aug 28 2015, 15:00) *
"Не помогает".

И не должно sm.gif

Просто так макросы не стоит писать, а то потом замучаетесь искать глюки при вызовах:
Код
MACRO(a + b);
MACRO(a ? b : c);


Ну и ';' в макросе тоже делать нечего.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Aug 28 2015, 12:12
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Если говорить про стиль макрописания. То как только в макросе возникает символ "\" руки должны автоматически выводить
Код
do { \
<тело макроса> \
} while (0)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 28 2015, 12:13
Сообщение #9


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(aaarrr @ Aug 28 2015, 15:08) *
Просто так макросы не стоит писать, а то потом замучаетесь искать глюки при вызовах:

В-общем, да. Но в данном примере я всегда буду подавать конкретное число.
Цитата
Ну и ';' в макросе тоже делать нечего.

Аналогично. Заменил макро функцией, которая вызывается конкретно, ничего не возвращает, внутри выражений не участвует.

P.S. На Кейл я гнал зря! laughing.gif

P.P.S. Еще добавил константу, чтобы задержка была не меньше требуемой. К единицам измерения добавил суффиксы ULL. Благодать.
DelayFourCycles((VALUE * UNIT * (SYSCLK / 1000000) + 3999) / 4000);
Go to the top of the page
 
+Quote Post
Mihey_K
сообщение Aug 28 2015, 13:47
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 156
Регистрация: 27-09-06
Из: Irkutsk
Пользователь №: 20 747



Цитата
Сначала любые операнды типа CHAR или SHORT преобразуются в
INT, а любые операнды типа FLOAT преобразуются в DOUBLE.
Затем, если какой-либо операнд имеет тип DOUBLE, то другой
преобразуется к типу DOUBLE, и это будет типом результата.
В противном случае, если какой-либо операнд имеет тип LONG,
то другой операнд преобразуется к типу LONG, и это и будет
типом результата.
В противном случае, если какой-либо операнд имеет тип
UNSIGNED, то другой операнд преобразуется к типу UNSIGNED,
и это будет типом результата.
В противном случае оба операнда будут иметь тип INT, и это
будет типом результата.
Керниган, Ричи. Язык C, гл. 14.6. Арифметические преобразования
Учиться никогда не поздно sm.gif


--------------------
Блог о разработке на CC430, SIM900, GPS, ARM и не только...
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 28 2015, 14:26
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Сначала любые операнды типа CHAR или SHORT преобразуются в
INT, а любые операнды типа FLOAT преобразуются в DOUBLE.

Это руководство к действию или описание происходящего?
Что - то как то странно звучит....
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 14:46
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Kabdim @ Aug 28 2015, 15:12) *
Если говорить про стиль макрописания. То как только в макросе возникает символ "\" руки должны автоматически выводить
CODE
do { \
<тело макроса> \
} while (0)

Сюрприз!
Вообще-то именно "\" НУ СОВСЕМ НИКАКОГО отношения не имеет к необходимости использования трюка do{}while(0)
Почему - подумайте самостоятельно.
Да и сам трюк, увы, грязноват, ибо while(константа) принципиально ошибочное выражение, хотя из-за его распространенности большинство компиляторописателей забили на предупреждение sad.gif



QUOTE (Golikov A. @ Aug 28 2015, 17:26) *
Это руководство к действию или описание происходящего?
Что - то как то странно звучит....

Это K&R, так-что это Ваш вопрос как-то странно звучит sm.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 28 2015, 14:57
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Aug 28 2015, 17:46) *
Да и сам трюк, увы, грязноват, ибо while(константа) принципиально ошибочное выражение, хотя из-за его распространенности большинство компиляторописателей забили на предупреждение sad.gif

В чем состоит принципиальная ошибка?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 15:02
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (aaarrr @ Aug 28 2015, 17:57) *
В чем состоит принципиальная ошибка?

В бессмысленности получившегося выражения. По этой причине прилично-бы выдать warning. IAR-у можно включить. Но у большинства - нет sad.gif



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 28 2015, 15:13
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(zltigo @ Aug 28 2015, 18:02) *
В бессмысленности получившегося выражения. По этой причине прилично-бы выдать warning. IAR-у можно включить. Но у большинства - нет sad.gif

Видимо, компиляторостроители должны дать возможность отключать подобные предупреждения только для макросов. Потому что макросы побуждают к творчеству креативных макросописателей, и у них часто получается что-то интересное и полезное. И я не стану спешить осуждать их за "бессмыссленность" чего-то там. Так что мяч на стороне компиляторостроителей.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Aug 28 2015, 15:16
Сообщение #16


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Огласите пожалуйста решение лучше. Думаю многим было бы интересно на него посмотреть.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 28 2015, 15:18
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Бессмысленной можно было бы признать запись while(0) {...} - тут warning был бы вполне уместен, но в случае do {...} while(0) одна итерация будет выполнена, так что смысл остается (пусть только для помянутой обертки от макроса).
Go to the top of the page
 
+Quote Post
Mihey_K
сообщение Aug 28 2015, 15:21
Сообщение #18


Частый гость
**

Группа: Участник
Сообщений: 156
Регистрация: 27-09-06
Из: Irkutsk
Пользователь №: 20 747



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

Сообщение отредактировал Mihey_K - Aug 28 2015, 15:24


--------------------
Блог о разработке на CC430, SIM900, GPS, ARM и не только...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 16:17
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Kabdim @ Aug 28 2015, 18:16) *
Огласите пожалуйста решение лучше. Думаю многим было бы интересно на него посмотреть.

Давайте все-же по порядку. То, что глупость про "\" написали поняли?


QUOTE (aaarrr @ Aug 28 2015, 18:18) *
Бессмысленной можно было бы признать запись while(0) {...} - тут warning был бы вполне уместен

Бессмысленнен любой с константой.
QUOTE
в случае do {...} while(0) одна итерация будет выполнена, так что смысл остается (пусть только для помянутой обертки от макроса).

Нет смысла и в этом, ибо для одной итерации достаточно {....}
Так-что весь этот трюк из-за ";" и не для чего более.

QUOTE (Mihey_K @ Aug 28 2015, 18:21) *
там почти все макросы переносом строки,

Да не имеет никкакого отношения склеивание строк к причинам использования этого трюка. ЛЮБОЙ макрос содержащий БОЛЕЕ одного выражения, хоть в одной строке, хоть в 999,
проблематичен при использовании типа такого:
if( )
MACRO();

Посему либо следить за тем, что-бы:
if()
{
MACRO();
}
либо трюк использовать,

Либо только {}, но тогда так
if()
MACRO()


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 28 2015, 17:09
Сообщение #20


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(scifi @ Aug 28 2015, 16:01) *
Почему-то думал, что ViKo - бывалый. А он в таких азах плавает laughing.gif

Думал, раз первое действие - с ULL числами, то препроцессор "запомнит", с чем имеет дело. А дальше искал, где же оно переполняется.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 28 2015, 17:22
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



вообще то, насколько я помню трюк
do
while(0)
создан для того чтобы в теле можно было в любой момент поставить break или continue и вывалиться из цикла, то есть закончить кусок кода без применения нелюбимого и кое где запрещенного оператора goto. Интересное использование в качестве превращение группы операторов в один, чтобы он под условие влезал без скобок...

символ переноса строки используется для переноса строки без ее разрыва. Дефайн требует объявление в 1 строку, а от этого падает читаемость. Но думая про то что много строк - это обычно надо для множества операторов, то может правило все пихать сразу под ду-вайл(0) для универсальности макроса может и имеет смысл....

while(1), while(0) имеет тот же смысл что описан в стандарте, никаких конструкций и правил он не нарушает, потому имеет право на жизнь и использование в тексте, ровно как и
for(;;). Наличие или отсутствие варнинга - это на усмотрение среды, ибо любые варнинги - это предупреждения от пользователя о возможных ошибках. И тут нет вопроса забили или не забили. Просто все посчитали что доставать пользователя таким варнингом излишне...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 28 2015, 17:31
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Aug 28 2015, 19:17) *
Бессмысленнен любой с константой.

Тогда и любимый Вами for(;;) столь же бессмысленнен, т.к. по сути цикл с константой в управляющем выражении.
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 28 2015, 17:39
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(ViKo @ Aug 28 2015, 20:09) *
Думал, раз первое действие - с ULL числами, то препроцессор "запомнит", с чем имеет дело. А дальше искал, где же оно переполняется.

Только препроцессор тут ни при чём. Препроцессор считает только тогда, когда ему нужно вычислить условие #if. А здесь считает компилятор.

Цитата(aaarrr @ Aug 28 2015, 20:31) *
Тогда и любимый Вами for(;;) столь же бессмысленнен, т.к. по сути цикл с константой в управляющем выражении.

Да это вообще абракадабра. Во всяком случае, любой вменяемый человек понимает, что "while (1)" - это "пока всегда", и по ошибке такое не напишет никто. Так что аргумент с предупреждениями компилятора притянут за все места. Хотя я сам пишу "for (;;)", но это дело вкуса...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 28 2015, 17:51
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(scifi @ Aug 28 2015, 20:39) *
Да это вообще абракадабра. Во всяком случае, любой вменяемый человек понимает, что "while (1)" - это "пока всегда", и по ошибке такое не напишет никто. Так что аргумент с предупреждениями компилятора притянут за все места. Хотя я сам пишу "for (;;)", но это дело вкуса...

Именно. Управляющее выражение может быть константой (явной или неявной). Все это - while(1) {}, for(;;) {}, do {} while(0) - нормальные и однозначно трактуемые языковые конструкции.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 28 2015, 17:57
Сообщение #25


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



напишите for ( ; true; ), если пустота не нравится. rolleyes.gif
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 28 2015, 18:01
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Сначала любые операнды типа CHAR или SHORT преобразуются в
INT, а любые операнды типа FLOAT преобразуются в DOUBLE.


а в стандарте

Цитата
First, if the corresponding real type of either operand is long double, the other
operand is converted, without change of type domain, to a type whose
corresponding real type is long double.

Otherwise, if the corresponding real type of either operand is double, the other
operand is converted, without change of type domain, to a type whose
corresponding real type is double.

Otherwise, if the corresponding real type of either operand is float, the other
operand is converted, without change of type domain, to a type whose
corresponding real type is float.


то есть я не вижу обязательного перевода в даблу всегда. Более того
float a;
float b;
float c = a + b;
я всегда считал что оно во флотах будет считаться, а не в даблах, а если любой операнд сначала перейдет в даблы
то даже написав (float)a + (float)b мы все равно получаем даблы, и следовательно долгий счет....
так что K&R G&A D&F и что-бы они ни было, по мне оно звучит странно.... я в чем то не прав?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 18:05
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (aaarrr @ Aug 28 2015, 20:31) *
Тогда и любимый Вами for(;;) столь же бессмысленнен, т.к. по сути цикл с константой в управляющем выражении.

АБСОЛЮТНО адекватное выражение и по этой причине является официально-страндартым вариантом для бесконечного цикла.
Это есть цикл без проверки условия, а не цикл с проверкой того, что измениться не может.
Неадекватным оно было-бы в виде for( ; 1 ; )



QUOTE (aaarrr @ Aug 28 2015, 20:51) *
Именно. Управляющее выражение может быть константой (явной или неявной). Все это - while(1) {}, for(;;) {}, do {} while(0) - нормальные и однозначно трактуемые языковые конструкции.

1 и 3 НЕТ. Вменяемые компиляторы выдают warnig именно по причине того, что константное "управляющее выражение" бессмысленно. Отключаемый, но warning.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 28 2015, 18:06
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Aug 28 2015, 21:03) *
Это есть цикл без проверки условия, а не цикл с проверкой того, что измениться не может.

Да ну! А в стандарте написано, что опущенное управляющее выражение заменяется ненулевой константой:
Цитата
An omittedexpression-2is replaced by a nonzero constant.


То есть неявно превращается в "цикл с проверкой того, что измениться не может".
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 18:09
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (scifi @ Aug 28 2015, 20:39) *
Да это вообще абракадабра.

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 28 2015, 18:11
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



вот я знаю пример явно ошибочного выражения

Код
int a = 10;
int b = 20;
int MaxFromAandB;
if(a >b);
  MaxFromAandB = a;
else
  MaxFromAandB = b;


if(a >b);

тут и ошибка будет на else без if , и первый if явно зря за точка запятачен.... а обсуждаемые while(1), while(0) - это нормально
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 18:12
Сообщение #31


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (aaarrr @ Aug 28 2015, 21:06) *
Да ну! А в стандарте написано, что опущенное управляющее выражение заменяется ненулевой константой

Да, это описано ПОВЕДЕНИЕ компилятора. Но когда компилятор видит, что в результате выражения ЕМУ ПЕРЕДАННОГО получается константа, это однозначно тревожный факт указывающий, как минимум на потенциальную ошибку программиста.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Aug 28 2015, 18:27
Сообщение #32


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(zltigo @ Aug 28 2015, 20:17) *
Давайте все-же по порядку. То, что глупость про "\" написали поняли?

Согласен исключительно по порядку. Вы воспользовались возможностью указать на формальную неправоту. Согласен конечно.

Цитата(zltigo @ Aug 28 2015, 20:17) *
Бессмысленнен любой с константой.

Не могу сказать что я большой знаток стандарта C, но смутно помню что в стандарте есть определения undefined, unspecified, а вот "бессмысленного" не помню. Не могли бы вы указать где в стандарте говорится о том что цикл с константой бессмыслен?

Цитата(zltigo @ Aug 28 2015, 20:17) *
Нет смысла и в этом, ибо для одной итерации достаточно {....}
Так-что весь этот трюк из-за ";" и не для чего более.

Так подождите, есть всё таки оказывается смысл?

Ну и напомню. В прошлом своём посте я попросил привести полноценную замену "бессмысленной" конструкции. Как вы верно подметили "{...}" на полноценную замену не годится.


Сообщение отредактировал Kabdim - Aug 28 2015, 18:27
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 18:36
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Kabdim @ Aug 28 2015, 21:20) *
Не могли бы вы указать где в стандарте говорится о том что цикл с константой бессмыслен?

А давайте от обратного. В стандарте описаны ИМЕЮЩИЕ смысл синтаксические конструкции. Для do и while в constant expression НЕ упоминаются. Так-же в стандарте НЕ упомиается, что выражения на русском матерном с точки зрения компилятора бессмысленны. Означает-ли это, что их можно использовать и тоебовать от компилятора их понимания?
QUOTE
Ну и напомню. В прошлом своём посте я попросил привести полноценную замену "бессмысленной" конструкции. Как вы верно подметили "{...}" на полноценную замену не годится.

Полноценной заметой является ИСПОЛЬЗОВАНИЕ фигурных скобок при ВЫЗОВЕ макроса. И в том числе по этой причине, кстати, и существует старое правило магросы большими буквами именовать. Ну а do{ }while(0) есть трюк. Обычный трюк, не всегда переносимый трюк, коих наизобретено множество.



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 28 2015, 18:41
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Aug 28 2015, 21:12) *
Да, это описано ПОВЕДЕНИЕ компилятора. Но когда компилятор видит, что в результате выражения ЕМУ ПЕРЕДАННОГО получается константа, это однозначно тревожный факт указывающий, как минимум на потенциальную ошибку программиста.

Это справедливо, например, для такого случая:
Код
unsigned int e;
...
if(e >= 0)
{
}

Тут вменяемые компиляторы дают предупреждение.

Но подозревать потенциальную ошибку в while(0) или while(1) как-то странно.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 28 2015, 18:46
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



вот while(0) уже не интересно, а тезис что при вычислении всегда все float преобразуются в double меня заинтересовал. И я не нашел подтверждения в стандарте...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 18:50
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (aaarrr @ Aug 28 2015, 21:41) *
Но подозревать потенциальную ошибку в while(0) или while(1) как-то странно.

Ну интеллект компиляторов, конечно растет семимильными шагами и можно многое требовать от них. Но все-же надо прежде всего говорить об ОБЩИХ минимальных требованиях описаных стандартом. А там, даже специально посмотрел C11 sm.gif - такого требования не было и нет. Кроме того собственно компилятор НЕ знает, что в исходнике написано while( 1 ) - он получает после препроцессора текст, а там могло быть написано и while( EPRST - eklmn() + 1 ) Тут можно уже подозревать ошибку, или?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Petka
сообщение Aug 28 2015, 18:51
Сообщение #37


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(zltigo @ Aug 28 2015, 17:46) *
....
Да и сам трюк, увы, грязноват, ибо while(константа) принципиально ошибочное выражение, хотя из-за его распространенности большинство компиляторописателей забили на предупреждение sad.gif
....

Что-то задело меня это безапелляционное утверждение.

Для Си-программистов встраиваемых систем группа "энтузиастов" из индустрии разработала стандарт "MISRA C".
Приведу небольшую выдержку из стандарта редакции 2004 года.

Цитата
Rule 19.4 (required): C macros shall only expand to a braced initialiser, a constant,
a string literal, a parenthesised expression, a type qualifier, a
storage class specifier, or a do-while-zero construct.
[Koenig 82–84]
These are the only permitted uses of macros. Storage class specifiers and type qualifiers include
keywords such as extern, static and const. Any other use of #define could lead to unexpected
behaviour when substitution is made, or to very hard-to-read code.
In particular macros shall not be used to define statements or parts of statements except the use
of the do-while construct. Nor shall macros redefine the syntax of the language. All brackets of
whatever type ( ) { } [ ] in the macro replacement list shall be balanced.
The do-while-zero construct (see example below) is the only permitted mechanism for having
complete statements in a macro body. The do-while-zero construct is used to wrap a series of one
or more statements and ensure correct behaviour. Note: the semicolon must be omitted from the
end of the macro body.
For example:
Код
/* The following are compliant */
#define PI 3.14159F /* Constant */
#define XSTAL 10000000 /* Constant */
#define CLOCK (XSTAL/16) /* Constant expression */
#define PLUS2(X) ((X) + 2) /* Macro expanding to expression */
#define STOR extern /* storage class specifier */
#define INIT(value){ (value), 0, 0} /* braced initialiser */
#define CAT (PI) /* parenthesised expression */
#define FILE_A "filename.h" /* string literal */
#define READ_TIME_32() \
do { \
    DISABLE_INTERRUPTS (); \
    time_now = (uint32_t)TIMER_HI << 16; \
    time_now = time_now | (uint32_t)TIMER_LO; \
    ENABLE_INTERRUPTS (); \
} while (0) /* example of do-while-zero */
/* the following are NOT compliant */
#define int32_t long /* use typedef instead */
#define STARTIF if( /* unbalanced () and language redefinition */
#define CAT PI /* non-parenthesised expression */


Так что если заниматься программированием для встраиваемых систем, такая нотация макросов является не только "допустимой", но и обязательной (с точки зрения MISRA C).
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Aug 28 2015, 18:55
Сообщение #38


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Демагогия в техническом споре... свежо! И легко опровергаемо. cool.gif

Цитата(zltigo @ Aug 28 2015, 22:36) *
А давайте от обратного. В стандарте описаны ИМЕЮЩИЕ смысл синтаксические конструкции. Для do и while в constant expression НЕ упоминаются. Так-же в стандарте НЕ упомиается, что выражения на русском матерном с точки зрения компилятора бессмысленны. Означает-ли это, что их можно использовать и тоебовать от компилятора их понимания?

Для do и while зато упоминаются expression. А constant expression частный случай expression.
Список допустимых символов для идентификаторов вполне прописан. Более того, если память меня не подводит, задекларирована максимальна длинна идентификатора. Так что требовать вы конечно можете, но исключительно для забавы. И придется освоить технику малолетних шкетов и выводить "<удалил транслит>" и тому подобное в рамках осмысленного по стандарту набора символов.


Цитата(zltigo @ Aug 28 2015, 22:36) *
Полноценной заметой является ИСПОЛЬЗОВАНИЕ фигурных скобок при ВЫЗОВЕ макроса. И в том числе по этой причине, кстати, и существует старое правило магросы большими буквами именовать. Ну а do{ }while(0) есть трюк. Обычный трюк, не всегда переносимый трюк, коих наизобретено множество.

Ну я так понимаю что ответа по существу дождаться не получится. Но с другой стороны вы дали новую интересную тему. Уточните пожалуйста на какие платформы этот трюк непереносим? Это ведь значит что "грязный трюк" не соответствует стандарту?

Сообщение отредактировал Kabdim - Aug 28 2015, 19:02
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 18:55
Сообщение #39


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Petka @ Aug 28 2015, 21:51) *
Так что если заниматься программированием для встраиваемых систем, такая нотация макросов является не только "допустимой", но и обязательной (с точки зрения MISRA C).

Это просто борьба с потенциальной ошибкой, котороая ДЕЙСТВИТЕЛЬНО имеет очень большую вероятность быть сделанной. Вот по этой причине и пошли на соглащение, что тут уж все способы хороши.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 28 2015, 18:58
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(zltigo @ Aug 28 2015, 21:50) *
Ну интеллект компиляторов, конечно растет семимильными шагами и можно многое требовать от них.

Да!

Цитата(zltigo @ Aug 28 2015, 21:50) *
Кроме того собственно компилятор НЕ знает, что в исходнике написано while( 1 ) - он получает после препроцессора текст, а там могло быть написано и while( EPRST - eklmn() + 1 ) Тут можно уже подозревать ошибку, или?

Нет!
Я вас умоляю! Что за бред? Это же не квадратура круга. Исходник есть, а компилятор не знает, что в нём? Если компиляторописатель не смог разрулить эту проблему, то он двоечник. Нормальному студенту-второкурснику это под силу.
Блин, я негодую crying.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 28 2015, 18:59
Сообщение #41


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Aug 28 2015, 21:50) *
...компилятор НЕ знает, что в исходнике написано while( 1 ) - он получает после препроцессора текст, а там могло быть написано и while( EPRST - eklmn() + 1 ) Тут можно уже подозревать ошибку, или?

Препроцессором можно и черное в белое превратить при желании.
Go to the top of the page
 
+Quote Post
Petka
сообщение Aug 28 2015, 19:13
Сообщение #42


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(zltigo @ Aug 28 2015, 21:55) *
Это просто борьба с потенциальной ошибкой, котороая ДЕЙСТВИТЕЛЬНО имеет очень большую вероятность быть сделанной. Вот по этой причине и пошли на соглащение, что тут уж все способы хороши.

1) С точки зрения стандарта Си конструкция do-while-zero не является "Implementation-Defined Behavior", "Undefined behavior" или пр. Так что поводов "давать по рукам" программисту никаких нет.
2) Уважаемый Вами инструмент от "IAR Systems" имеет возможность проверять в том числе и правила "MISRA C". Было бы забавно наблюдать что на единственно возможную конструкцию согласно правилам "MISRA C" транслятор при проверке будет выдавать предупреждение. smile3046.gif
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 28 2015, 19:13
Сообщение #43


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Golikov A. @ Aug 28 2015, 21:01) *
я всегда считал что оно во флотах будет считаться, а не в даблах, а если любой операнд сначала перейдет в даблы
то даже написав (float)a + (float)b мы все равно получаем даблы, и следовательно долгий счет....
так что K&R G&A D&F и что-бы они ни было, по мне оно звучит странно.... я в чем то не прав?

Все правильно: действующий стандарт отличается от того, что описан у K&R в старой редакции.
Нужно только помнить, что константы все равно по умолчанию интерпретируются как double, т.е. 1.234 - это double, а 1.234F - float.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 19:22
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (scifi @ Aug 28 2015, 21:58) *
Я вас умоляю! Что за бред?
Блин, я негодую crying.gif

Увы, это совершеная реальность - ПЕРЕД компиляцией сишный исходник проходит через препроцессор. Удивлен немало, что это для Вас новость sad.gif.


QUOTE (Petka @ Aug 28 2015, 22:13) *
Было бы забавно наблюдать что на единственно возможную конструкцию согласно правилам "MISRA C" транслятор при проверке будет выдавать предупреждение. smile3046.gif

Не смотря на то, что Вам так забавно, все так и происходит, если активизировать полный набор warnings. По умолчанию - не ругается.


QUOTE (Petka @ Aug 28 2015, 22:13) *
С точки зрения стандарта Си конструкция do-while-zero не является "Implementation-Defined Behavior", "Undefined behavior" или пр. Так что поводов "давать по рукам" программисту никаких нет.

Не давать, а ПРЕДУПРЕЖДАТЬ, что написанная программистом конструкция была бессмысленна и комилятор нее выкинул, но может программист не пожалевший времени на нажатие кнопок, все-же расситывал на какой-то другой эффект???


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Petka
сообщение Aug 28 2015, 19:37
Сообщение #45


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(zltigo @ Aug 28 2015, 22:22) *
Не смотря на то, что Вам так забавно, все так и происходит, если активизировать полный набор warnings. По умолчанию - не ругается.

Резюме: "вменяемый компилятор" по умолчанию не выдаёт предупреждение на вполне законную конструкцию. Плюсик к IAR Systems.
Цитата
Не давать, а ПРЕДУПРЕЖДАТЬ, что написанная программистом конструкция была бессмысленна и компилятор нее выкинул, но может программист не пожалевший времени на нажатие кнопок, все-же рассчитывал на какой-то другой эффект???

В качестве литературной гиперболы:

в конструкции:
Код
r = (a * b) + (c * d);

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

P.S. Модераторам: из топика имеет смысл обсуждение конструкции do-while-zero вынести в отдельную тему.
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 28 2015, 21:14
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(zltigo @ Aug 28 2015, 22:22) *
Увы, это совершеная реальность - ПЕРЕД компиляцией сишный исходник проходит через препроцессор. Удивлен немало, что это для Вас новость sad.gif.

Вы будете смеяться, но перед вёрсткой текст книги проходит корректора, редактора и кого-то там ещё, наверное. И вы утверждаете, что редактор не может посмотреть на то, на что смотрит корректор? Пардон, но какую траву вы курите? Исходный текст злобные чекисты спрятали что ли? Я вас умоляю... twak.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 21:32
Сообщение #47


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (scifi @ Aug 29 2015, 00:14) *
Пардон, но какую траву вы курите? Исходный текст злобные чекисты спрятали что ли? Я вас умоляю... twak.gif

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



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 28 2015, 21:40
Сообщение #48


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(zltigo @ Aug 29 2015, 00:32) *
От того, что Вы будете повторять дурь находящуюся в Вашей голове, Ваши фантазии о том, как должен работать препроцессор + компилятор ничего не изменят.

Мне более не интересно пытаться донести свою мысль до вас. Адью.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 21:43
Сообщение #49


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Petka @ Aug 28 2015, 22:37) *
в конструкции:
CODE
r = (a * b) + (c * d);

тоже есть "лишние конструкции", которые транслятор "выкинет". Например, скобки вообще "лишние". Да и пробелы совсем не нужны. Может программист "все-же рассчитывал этими скобками на какой-то другой эффект"?

Вы, очевидно не поверите, но компилятор скобки не "выкинет", он выполнит НЕ РАСУЖДАЯ предписанные ими действия. С пробелами еще проще - их игнорирование описано стандартом, так-что компилятор де-юре не думает, что кто хотел сказать пробелами.
QUOTE
P.S. Модераторам: из топика имеет смысл обсуждение конструкции do-while-zero вынести в отдельную тему.

Уже была когда-то. Вторая никчему.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Petka
сообщение Aug 28 2015, 22:09
Сообщение #50


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(zltigo @ Aug 29 2015, 00:43) *
Вы, очевидно не поверите,

Очевидно, тут не вопрос веры.
Цитата
но компилятор скобки не "выкинет", он выполнит НЕ РАССУЖДАЯ предписанные ими действия. С пробелами еще проще - их игнорирование описано стандартом, так-что компилятор де-юре не думает, что кто хотел сказать пробелами.

Сказали "А", говорите и "Б". Если "лишние" пробельные символы компилятор может удалять(игнорировать) без предупреждений, то и валидные конструкции "while(0)", "for(;;)", "#if 0", по той-же самой логике транслятор должен обрабатывать согласно стандарту "НЕ РАССУЖДАЯ".
Что бы не уводить обсуждение в сторону прошу подкрепить или опровергнуть Ваше заявление
Цитата
...Да и сам трюк, увы, грязноват, ибо while(константа) принципиально ошибочное выражение, хотя из-за его распространенности...

Откуда вы это взяли? Есть какой-то стандарт где это описано? Отраслевые инструкции? Исследования? В книжке какой-то прочитали? Бложик? Твиттер? Сплетни? С удовольствием ознакомлюсь с источником такой информации.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 28 2015, 23:39
Сообщение #51


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Petka @ Aug 29 2015, 01:09) *
Откуда вы это взяли? Есть какой-то стандарт где это описано?

Стандарт языка Cи, надо читать и ПОНИМАТЬ написанное. for( ; ; ) абсолютно ОДНОЗНАЧНОЕ указание компилятору сгенерировать цикл БЕЗ проверки каких либо условий. Любой другой вариант уже требует проверки, а для выкидывания ненужной проверки уже наличия минимальной, но оптимизации. Начинать думать можете начать с того, что в в примерах стандарта вечный цикл for( ; ; ) и нет ни одного while( CONST ) у K&R совершенно аналогично. Ни то ни другое не есть -
QUOTE
Бложик? Твиттер? Сплетни?
С удовольствием ознакомлюсь с источником такой информации.

Знакомьтесь.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 29 2015, 03:34
Сообщение #52


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
у K&R совершенно аналогично.

Это вообще странный авторитет, особенно в свете последней выдержки с преобразованием типов....

Цитата
Стандарт языка Cи, надо читать и ПОНИМАТЬ написанное.

Надо, и в нем нет запрета на конcтрукцию while(0) и while(1), ровно как и нет неоднозначного толкования как она будет выполнена.

Ошибкой является утверждение что это "принципиально ошибочное" выражение, оно даже потенциально не ошибочное, не то что принципиально....

Цитата
Нужно только помнить, что константы все равно по умолчанию интерпретируются как double, т.е. 1.234 - это double, а 1.234F - float.
Это понятно, и наличие этой константы в виде дабла по стандарту затянет все выражение в расчет в даблах. Но все же можно вести счет во флотах и это принципиально важно, это же ускорение за счет аппаратных модулей.... и по мне вот это гораздо важнее того как сделан вечный цикл через for(;;) или через while(1)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 29 2015, 04:30
Сообщение #53


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Что вы сцепились на пустом. Я вот ни разу не использовал do { } while (0), и ничего. Программы работают, как задумано.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 29 2015, 04:52
Сообщение #54


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ща и вам достанетсяsm.gif.... как вы могли ни разу не использовать?!!!
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 29 2015, 05:00
Сообщение #55


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Golikov A. @ Aug 29 2015, 07:52) *
ща и вам достанетсяsm.gif.... как вы могли ни разу не использовать?!!!

Ничего, с меня не убудет. Я авторитетом себя не считаю. Просто стараюсь писать аккуратно, не упуская нужных символов и не лепя ненужных. Пробелы не в счет, на них не экономлю. Например, если мне надо 1 << 7 + 16, то так и пишу. Хотя компилятор ругается предупреждением (не компилятор, а сама среда в Кейле значок ставит).

А VALUE я, пожалуй, в скобки возьму. Вдруг захочется мне (или кому-то другому) задать задержку в виде DELAY(2 + 2, _MS).
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 06:04
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Golikov A. @ Aug 29 2015, 06:34) *
Надо, и в нем нет запрета на конcтрукцию while(0) и while(1), ровно как и нет неоднозначного толкования как она будет выполнена.

Уже писал - в стандарте нет запрета на использование русских матерных слов, тем неменее компиляторы не захотят компилировать такие выражения. Точно так-же, как компиляторы, пусть даже и не все, таки выдают предупреждения на while( CONST ). Так-что давайте Вы свой талант толкователя стандартов будете демонстрировать не мне.



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 29 2015, 06:22
Сообщение #57


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Уже писал - в стандарте нет запрета на использование русских матерных слов

ну как же нет? Есть стандарт формирования имен переменных и список ключевых слов. Ваши матерные выражения не попадают в множество которые возможно создать по данным правилам, потому их и нельзя использовать....

Цитата
Так-что давайте Вы свой талант толкователя стандартов будете демонстрировать не мне.

А вы не читайте....

Цитата
Хотя компилятор ругается предупреждением (не компилятор, а сама среда в Кейле значок ставит).

а что за значок?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 29 2015, 07:10
Сообщение #58


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Golikov A. @ Aug 29 2015, 09:22) *
а что за значок?

Восклицательный знак в желтом треугольнике напротив опасной строки. rolleyes.gif И подчеркивает красненьким опасное место.
При наведении мыши на подчеркнутое или на значок выдается:
warning: operator '<<' has lower precedence than '+'; '+' will be evaluated first
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 29 2015, 09:37
Сообщение #59


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Aug 28 2015, 22:12) *
Но когда компилятор видит, что в результате выражения ЕМУ ПЕРЕДАННОГО получается константа, это однозначно тревожный факт указывающий, как минимум на потенциальную ошибку программиста.

Какую ошибку? Условие/выражение может быть опционально вычисляемое в рунтайме. Или в какой-то опции проекта вычисляемое на этапе компиляции. Но место проверки условия задаёт тип цикла и его устанавливает программер исходя из оптимальности алгоритма, в том числе опционального удобства.

Подозревать препроцессор в перетрахе только выражений - мало. Это текстовый препроцессор и он может заменять любое место исходника. for (;;) мог быть перед препроцессором for (A;B;C) где A, B, C дефайном задавались пустыми или не пустыми. Потенциальность ошибки зацитированным методом компилятору не определить.

----
Цитата(zltigo @ Aug 28 2015, 22:50) *
Ну интеллект компиляторов, конечно растет семимильными шагами и можно многое требовать от них.

У zltigo могло бы быть большое будущее во главе какого-нибудь ЦБ, ну или будучи физиком-теоретиком. Умеет фундаментализировать инфляцию. Инфляцию отсутствия ошибок через повышение интеллекта компилятора. А так же переориентируя точку отсчёта на прокладку препроцессор.

Сообщение отредактировал GetSmart - Aug 29 2015, 09:56


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 09:53
Сообщение #60


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Golikov A. @ Aug 28 2015, 20:22) *
вообще то, насколько я помню трюк
do
while(0)
создан для того чтобы в теле можно было в любой момент поставить break или continue и вывалиться из цикла, то есть закончить....

Да ну! Вообще-то дело обстоит с точностью до наоборот.
1) break это выход из ЛЮБОГО цикла и городить для этого while(0) совершенно незачем.
2) именно ИСПОЛЬЗОВАНИЕ do while(0) в обертке макроса приводит в ПОБОЧНОМУ эффекту выхода по break из макроса ну СОВСЕМ не туда.


QUOTE (GetSmart @ Aug 29 2015, 12:37) *
Какую ошибку?

Ошибку того, что программист получил не то, что он думал. Ибо компилятор получил в качестве инструкции БЕССМЫСЛЕННОЕ, хотя и однозначное выражение. Дальше у компилятора два варианта - решить, что это написал не программист а "Джамшут" и не пытаться от него чего-либо еще добиваться, либо таки сообщить о подозрительном выражении.
Для определения "Джамшут"/программист у хороших компиляторов есть опция соответствующего warnig.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 29 2015, 09:58
Сообщение #61


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Aug 29 2015, 13:53) *
Ошибку того, что программист получил не то, что он думал. Ибо компилятор получил в качестве инструкции БЕССМЫСЛЕННОЕ, хотя и однозначное выражение. Дальше у компилятора два варианта - решить, что это написал не программист а "Джамшут" и не пытаться от него чего-либо еще добиваться, либо таки сообщить о подозрительном выражении.
Для определения "Джамшут"/программист у хороших компиляторов есть опция соответствующего warnig.

Это уже не потенциальные, а реально НЕОБОСНОВАННЫЕ обвинения и опасения. Контраргументация ранее была изложена в достаточном объёме.

------

Предлагаю желающим обсудить другой криминал. Не запрещено ли всевышним использование пустых фигурных скобок. А так же точки с запятой после скобок. Или внутри скобок обязательно должна стоять хотя бы точка с запятой. Часто циклы ожидания какого-то события делают пустыми, а в конце {};

Сообщение отредактировал GetSmart - Aug 29 2015, 10:19


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 10:14
Сообщение #62


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (GetSmart @ Aug 29 2015, 12:58) *
Контраргументация ранее была изложена в достаточном объёме.

Попробуйте убедить своей "контраргументацией" разработчиков компиляторов, которые ругаются на while(CONST). Мне рассказывать, что ныне принято писать дерьмокод и посему это "нормально", пожалуйста, не надо.
Из гарантированно мне известных это IAR и MS. Из гарантрованно плюющих помню только GCC.



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 29 2015, 10:22
Сообщение #63


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



А разве while(1) не сам всевышний написал? sm.gif

Цитата(zltigo @ Aug 29 2015, 14:14) *
Попробуйте убедить своей "контраргументацией" разработчиков компиляторов, которые ругаются на while(CONST). Мне рассказывать, что ныне принято писать дерьмокод и посему это "нормально", пожалуйста, не надо.
Из гарантированно мне известных это IAR и MS. Из гарантрованно плюющих помню только GCC.

IAR в СИ-коде не выдаёт error или warning на while (Const). Если читаете ремарки Иара, то не передёргивайте.

---
Надо создать доску позора с необоснованными ошибками компиляторов. Сам иногда удивляюсь логике ругательств.

Сообщение отредактировал GetSmart - Aug 29 2015, 11:33


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 10:32
Сообщение #64


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (GetSmart @ Aug 29 2015, 13:22) *
А разве while(1) не сам всевышний написал? sm.gif

Всевышний, как написано в библии K&R а так-же в примерах в стандарте, в том числе и C11, написал совершенно однозначное for( ; ; ) sm.gif Потом уже еретики начали писать while(1),while(2),while(3),.....,while(TRUE),while(true),while((_Bool)1) и так далее. Причем без всякой на то надобности.


QUOTE (GetSmart @ Aug 29 2015, 13:22) *
Надо создать доску позора с необоснованными ошибками компиляторов. Сам иногда удивляюсь логике ругательств.

Начние с MISRA - там МНОГО веселее sm.gif. А с компиляторами все просто - если по какой-то причине, пусть даже по причине собвстенного несовершенства, компилятор сомневается, как понять, лучше пусть ПРЕДУПРЕЖДАЕТ. Я, если вдруг не смогу выразить мысль в однозначно понятной компилятору форме, лучше прагмой в этом месте сообщение подавлю, нежели получу неведомо что.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 29 2015, 10:43
Сообщение #65


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



У цикла while только один аргумент - предусловие выполнения. Этот цикл логически естественнен для многих алгоритмов.

Цитата(zltigo @ Aug 29 2015, 14:32) *
А с компиляторами все просто - если по какой-то причине, пусть даже по причине собвстенного несовершенства, компилятор сомневается, как понять, лучше пусть ПРЕДУПРЕЖДАЕТ.

Компилятор Кейла ругается ошибкой на STM Rz!,{Rx-Ry} если Rz находется внутри сохраняемых регистров. Ошибка, не предупреждение. Писатели компиляторов слишком много себе позволяют.

Сообщение отредактировал GetSmart - Aug 29 2015, 10:39


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 29 2015, 11:25
Сообщение #66


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Что касается предупреждений по поводу управляющего выражения, то тут, по-моему, стоит разделять два случая:

1. Когда выражение изначально представляет собой константу:
Код
while(1) {...}

if(123) {...} /* Правда, выглядит ужасно? */

Тут предупреждение явно ни к чему.

2. Когда выражение обращается в константу на этапе компиляции:
Код
unsigned int x;

if(x >= 0) {...}

В этом случае есть явный повод для предупреждения.

Оформление бесконечного цикла - это уже дело вкуса программиста. Я, пожалуй, соглашусь, что for(;;) {..} лучше, просто
на основании того, что if(1) {...} мне представляется ужасным. Но while(1) {...} все же ни малейшего отторжения не вызывает.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 11:35
Сообщение #67


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (GetSmart @ Aug 29 2015, 13:43) *
У цикла while только один аргумент - предусловие выполнения. Этот цикл логически естественнен для многих алгоритмов.

Я что-то писал о неестественности цикла? Нет? Возражения только против того, что именно-то и УСЛОВИЯ быть-то и НЕ должно, ибо цикл БЕЗУСЛОВНЫЙ. Вот посему for c ОТСУТСТВУЮЩИМ условием есть логично, а while c БЕССМЫСЛЕННЫМ ВЫРАЖЕНИМ условия, есть настораживающий факт.

QUOTE (aaarrr @ Aug 29 2015, 14:25) *
что if(1) {...} мне представляется ужасным.

Тем неменее изрядно часто используется if(0){...} для того что-бы закомментировать кусок исходника. Кому-то это уже ужасным не кажется sad.gif - типа очередной супертрюк - одним символом комментировать/раскомментировать. Задавлены предупреждения и понеслись писать говнокод.



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 29 2015, 11:57
Сообщение #68


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Гы-гы. Развели мегасрач на пустом месте. Модераторы за прыжок на месте расстреливают, а тут такое... Я их не понимаю laughing.gif
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 29 2015, 12:08
Сообщение #69


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Aug 29 2015, 15:35) *
Вот посему for c ОТСУТСТВУЮЩИМ условием есть логично, а while c БЕССМЫСЛЕННЫМ ВЫРАЖЕНИМ условия, есть настораживающий факт.

Все сразу отсутствующие аргументы лично у меня вызывают диссонанс. Как и do .. while (0) в дефайнах из-за доисторических компиляторов, выдававших варнинг на голую точку с запятой. Последнее напоминает решение проблемы через одно место.

Константа обязана быть корректным аргументом для опциональной совместимости. Бессмысленность, при желании, можно усмотреть даже в существовании людей. Или себя. И аргументировать это повышением уровня интеллекта/самосознания или сменой точки отсчёта. Вас уже просили использовать терминологию стандарта. У программистов есть законное право использовать любой из разрешённых вариантов.

Сообщение отредактировал GetSmart - Aug 29 2015, 12:46


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 29 2015, 14:55
Сообщение #70


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(ViKo @ Aug 29 2015, 10:10) *
Восклицательный знак в желтом треугольнике напротив опасной строки. rolleyes.gif И подчеркивает красненьким опасное место.
При наведении мыши на подчеркнутое или на значок выдается:
warning: operator '<<' has lower precedence than '+'; '+' will be evaluated first
На самом деле предупреждает не зря. Одно дело 1 << 7 + 16, а сам неоднократно накалывался на word = byte1 << 8 + byte2, хотя точно знаю, что приоритет у сложения выше. И только благодаря этому предупреждению не тратил время на поиски очевидной, но тем не менее пролетающей между глаз ошибки.

По поводу вашего спора о do {} while (0). Единственное место, где это выражение необходимо - подобный функции макрос из более чем одного выражения. Который можно не задумываясь и однообразно вставлять в любое место, где допустим вызов функции, в том числе и в выражение if(cond) macro(); else ... И идите лесом с убеждениями меня в бессмысленности while(0) - он здесь делает именно то, что от него требуется. И я буду его использовать в линейном коде do { if(!func1()) break;... if(!func2()) break; ..... } while(0); потому что это совершенно однозначная конструкция, существенно упрощающая исходник. И мне глубоко фиолетово, что кому-то она эстетически неприятна.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 14:59
Сообщение #71


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Сергей Борщ @ Aug 29 2015, 17:55) *
И мне глубоко фиолетово, что кому-то она эстетически неприятна.

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 29 2015, 15:42
Сообщение #72


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Ошибку того, что программист получил не то, что он думал

Горе тому программисту, который написав while(0) думает получить что то иное....
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 16:01
Сообщение #73


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Golikov A. @ Aug 29 2015, 18:42) *
Горе тому программисту, который написав while(0) думает получить что то иное....

Горе тому, кто не может ни думать (а чего тут думать - трясти надо писать while(1) надо - так все индийские студенты пишут) ни даже читать: http://electronix.ru/forum/index.php?showt...t&p=1361255
QUOTE
...собственно компилятор НЕ знает, что в исходнике написано while( 1 ) - он получает после препроцессора текст, а там могло быть написано и while( EPRST - eklmn() + 1 ) Тут можно уже подозревать ошибку, или?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 29 2015, 16:07
Сообщение #74


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Препроцессор тут с визгом притянут за уши. Это не аргумент. Совсем.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 16:20
Сообщение #75


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (aaarrr @ Aug 29 2015, 19:07) *
Препроцессор тут с визгом притянут за уши. Это не аргумент. Совсем.

А зачем писать на самом деле НЕПОНЯТНОЕ, хотя и "привычная", но бессмысленная конструкция while(1), на которую хоть и некоторые компиляторы, но ругатся (и правильно делают), вместо канонического варианта - цикл БЕЗ проверки условий, прямо для такого случая предусмотренного? Зачем?
Что это вообще - "пока один"? Ну? Тогда-уж агитировали-бы за while( 1 == 1 ) по любому бессмысленная проверка неизменного условия, но хоть какой-то смысл типа "понятнее" можно было притянуть.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 29 2015, 16:57
Сообщение #76


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Для zltigo:
Качество кода ремарками не измеряется. Не вводите в заблуждение читателей, называя их ругательством компилятора.

Например:
if (1) ... до препроцессора могло быть if (Expr) ..., где Expr определялось дефайном. Вся конструкция вызывала бы опциональную инициализацию периферии, например. В отличие от #if допускает даже рунтайм-условие (вроде Fclk > 100). И безусловно должно допускать простейшую константу или выражение, вычисляемое на этапе компиляции. Неполиткорректно называть это ужасным. Ну а что позволено if-у, то юпитеру while и подавно. ИМХО всё вполне читабельно.Так же ИМХО, должно вызывать ремарку компилятора, если условие известно на этапе компиляции.

Смысла в таких конструкциях более чем достаточно. Хватит вопить про бессмысленность и всякий криминал. Даже просто if (0 или 1) (это без вмешательства препроцессора) могло быть промежуточной (но 100% рабочей) версией кода, расчитанной на изменение условия в дальнейшем. Вобщем код опционален и этот блок можно включить или выключить по необозначенному явно условию. Смысл в константах есть. Нарушений стандарта нет.

Сообщение отредактировал GetSmart - Aug 29 2015, 17:31


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 29 2015, 17:12
Сообщение #77


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Aug 29 2015, 19:20) *
Что это вообще - "пока один"? Ну? Тогда-уж агитировали-бы за while( 1 == 1 ) по любому бессмысленная проверка неизменного условия, но хоть какой-то смысл типа "понятнее" можно было притянуть.

1 - это nonzero constant, как раз то, что возникает на пустом месте в for(;;)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 17:29
Сообщение #78


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (GetSmart @ Aug 29 2015, 19:57) *
Для zltigo:
Качество кода ремарками не измеряется. Не вводите в заблуждение читателей, называя их ругательством компилятора.

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 29 2015, 17:37
Сообщение #79


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Сергей Борщ @ Aug 29 2015, 17:55) *
На самом деле предупреждает не зря. Одно дело 1 << 7 + 16, а сам неоднократно накалывался на word = byte1 << 8 + byte2, хотя точно знаю, что приоритет у сложения выше. И только благодаря этому предупреждению не тратил время на поиски очевидной, но тем не менее пролетающей между глаз ошибки.

Согласен, здесь приоритеты не очевидны. Может, действительно, не жалеть скобок...
Надо было сделать приоритеты этих операторов равными.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 29 2015, 17:39
Сообщение #80


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Aug 29 2015, 21:29) *
Писатели не могущие четко выражать свои мысли компилятору получают такой-же нечеткий результат.

На while (const) ?

Критикуйте конструктивней и точечней. Необоснованность ругательств компиляторов нужно разбирать в каждом конкретном случае.

Компиляторописатели тоже лажают. Встречал граблю когда в конструкции if (0) стоит метка и вне if-а, ниже по коду, стоит на неё переход. Виновен компиляторописатель. Необычный код, но по стандарту ошибки нет.

Сообщение отредактировал GetSmart - Aug 29 2015, 17:58


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 17:39
Сообщение #81


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (aaarrr @ Aug 29 2015, 20:12) *
1 - это nonzero constant, как раз то, что возникает на пустом месте в for(;;)

А где все-же ответ на вопрос http://electronix.ru/forum/index.php?showt...t&p=1361373
QUOTE
А зачем писать на самом деле НЕПОНЯТНОЕ, хотя и "привычная", но бессмысленная конструкция while(1), на которую хоть и некоторые компиляторы, но ругатся (и правильно делают), вместо канонического варианта - цикл БЕЗ проверки условий, прямо для такого случая предусмотренного? Зачем?

?
А по поводу "возникновения" - уже отвечал: http://electronix.ru/forum/index.php?showt...t&p=1361241


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 29 2015, 17:40
Сообщение #82


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Кстати, я никогда не пишу #if (0) или #if (1), а только #if (true), #if (false)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 17:47
Сообщение #83


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (GetSmart @ Aug 29 2015, 20:39) *
Критикуйте конструктивней и точечней.

Читайте внимательнее и не фантазируйте. Warning на constant expression это не единственный warning выдаваемый компиляторами из тех, ктороые нерадивые любят давить.

QUOTE (ViKo @ Aug 29 2015, 20:40) *
Кстати, я никогда не пишу #if (0) или #if (1), а только #if (true), #if (false)

А смысл? Тем более для препроцессора, для которого это никаким боком не ключевые слова, как впрочем и для произвольного (не C11? C99?) Си компилятора. Только в свежих стандартах true и false определены и в том числе для препроцесора.

Зато какие прелесные эффекты будут с каким-нибудь GCC препроцессором, который молча без всяких предупреждений подсунет вместо недефинированого true нолик.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 29 2015, 18:05
Сообщение #84


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(zltigo @ Aug 29 2015, 20:47) *
А смысл? Тем более для препроцессора, для которого это никаким боком не ключевые слова, как впрочем и для произвольного (не C11? C99?) Си компилятора. Только в свежих стандартах true и false определены и в том числе для препроцесора.

Зато какие прелесные эффекты будут с каким-нибудь GCC препроцессором, который молча без всяких предупреждений подсунет вместо недефинированого true нолик.

На то есть #include <stdbool.h> А смысл - лично для меня, эстета. rolleyes.gif "Истина" круче "единицы".
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 18:07
Сообщение #85


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (ViKo @ Aug 29 2015, 21:05) *
На то есть #include <stdbool.h> А смысл - лично для меня, эстета. rolleyes.gif "Истина" круче "единицы".

Повторяю - ЕСЛИ ЕСТЬ, а есть только начиная, помнится, с C99, а если нет, то...


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ViKo
сообщение Aug 29 2015, 18:14
Сообщение #86


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(zltigo @ Aug 29 2015, 21:07) *
Повторяю - ЕСЛИ ЕСТЬ, а есть только начиная, помнится, с C99, а если нет, то...

Напомните, сколько лет прошло с 1999 года? Что ж цепляться за старое? В том, чем я пользуюсь, есть. Прикажете забить (забыть)?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 29 2015, 18:14
Сообщение #87


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Aug 29 2015, 21:47) *
Warning на constant expression это не единственный warning выдаваемый компиляторами из тех, ктороые нерадивые любят давить.

Список компиляторов в студию. И текст исходника. Экономьте время собеседников на уточнения.

Цитата
Для do и while зато упоминаются expression. А constant expression частный случай expression.

Сможете опровергнуть?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 29 2015, 18:18
Сообщение #88


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Aug 29 2015, 20:39) *
А где все-же ответ на вопрос http://electronix.ru/forum/index.php?showt...t&p=1361373

Зачем? Потому что это нормальная языковая конструкция.

Специально посмотрел: использую оба варианта, но чаще while(1). Объясняется это очень просто - в старые времена
компиляторы под ARM отвратительно компилировали циклы for, из-за чего повсеместно использовал do-while.
Потом пришлось специально заставлять себя писать for, потому как последний для обычных циклов нагляднее.
Но для бесконечного цикла разницы не делаю.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 18:39
Сообщение #89


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (ViKo @ Aug 29 2015, 21:14) *
Напомните, сколько лет прошло с 1999 года? Что ж цепляться за старое?

Абсолютно согласен, что использовать следует C99. Но жизнь, есть жизнь. Я вот до сих пор вынужден пользовать И компиляторы не поддерживающие C99. C99 просто нет. Есть и глупые варианты, например, пару месяцев назад начал рабтать с котроллерос с ядром BA22. Есть GCC toolchain весь из себя C99. Но весь говнокод идущий с контроллером компилируется не в С99. Какого черта - вопрос не ко мне, а к "программистам" тупо по умолчанию собравших. А там действительно чистый говнокод, который-бы сто лет не читал-бы, но он идет, в соответствии с новейшими тенденциями, ВМЕСТО документации sad.gif.


QUOTE (aaarrr @ Aug 29 2015, 21:18) *
Зачем? Потому что это нормальная языковая конструкция.

В вопросе, по причине того, что такой "ответ" повторяется вместо мантры, был сразу и второй - почему на "нормальную" ругаются компиляторы? Их разработчики так-же, как и я "заблуждаются"?




QUOTE (GetSmart @ Aug 29 2015, 21:14) *
Список компиляторов в студию

Не сочтите за труд ознакомится с ранее данным ответом на этот вопрос.


QUOTE (GetSmart @ Aug 29 2015, 21:14) *
Сможете опровергнуть?

Частные случаи на то и частные, что не всегда эквиваленты общим. По этой причне в стандарте эти понятия и РАЗДЕЛЕНЫ и constant expression в контесте while() НЕ упоминаются, в отличие, кстати, от for()

QUOTE (aaarrr @ Aug 29 2015, 21:18) *
Специально посмотрел: использую оба варианта, но чаще while(1). Объясняется это очень просто - в старые времена
компиляторы под ARM отвратительно компилировали циклы for, из-за чего повсеместно использовал do-while.

У меня еще для одного изделия на AM186CC еще живет BCC 3.1 за него, правда уже не уверен, но 2.0 для while( 1 ) генерил лишний код в цикле, в отличие от for( ; ; ).


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 29 2015, 18:44
Сообщение #90


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Aug 29 2015, 21:39) *
В вопросе, по причине того, что такой "ответ" повторяется вместо мантры, был сразу и второй - почему на "нормальную" ругаются компиляторы? Их разработчики так-же, как и я "заблуждаются"?

Как Вы сами заметили, уже перестают. Времена меняются, язык тоже.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 19:00
Сообщение #91


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (aaarrr @ Aug 29 2015, 21:44) *
Как Вы сами заметили, уже перестают. Времена меняются, язык тоже.

Язык, как базовый стандарт, в этом аспекте не меняется - что K&R, что C11 описывают все одинаково. Меняется ТОЛКОВАНИЕ и увеличивается количество говнокода которое коекодеры хотят компилировать чем попало, а авторы компиляторов хотят прежде всего получить новых пользователей и им никчему отталкивать кодеров у которых на "том компиляторе все работало" а этот компилятор "плохой" sad.gif. Так-что задача прежде всего собрать из под чужого компилятора и помешать (добавление диалектов) чужому собрать свое. Но тем неменее реальной, а не нарочито сделаной несовместимости компиляторов нет уже давно - нормально писаные исходники таскаются у меня по доброй дюжине компиляторов и 8-16-32-64 бит платформам.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Aug 29 2015, 19:10
Сообщение #92


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(zltigo @ Aug 29 2015, 21:39) *
Частные случаи на то и частные, что не всегда эквиваленты общим. По этой причне в стандарте эти понятия и РАЗДЕЛЕНЫ и constant expression в контесте while() НЕ упоминаются, в отличие, кстати, от for()

Чистой воды демагогия: в контексте оператора ^ тоже не упоминаются константы, так значит ли это, что их использовать нельзя?

Цитата(zltigo @ Aug 29 2015, 22:00) *
Меняется ТОЛКОВАНИЕ и увеличивается количество говнокода которое коекодеры хотят компилировать чем попало, а авторы компиляторов хотят прежде всего получить новых пользователей и им никчему отталкивать кодеров у которых на "том компиляторе все работало" а этот компилятор "плохой" sad.gif . Так-что задача прежде всего собрать из под чужого компилятора и помешать (добавление диалектов) чужому собрать свое.

Это было бы справедливо, если бы какие-нибудь из древних компиляторов считали while(const) ошибкой. Есть такие?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 29 2015, 19:28
Сообщение #93


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (aaarrr @ Aug 29 2015, 22:10) *
Чистой воды демагогия: в контексте оператора ^ тоже не упоминаются константы, так значит ли это, что их использовать нельзя?

Стандарт языка Cи был и есть лаконичен и многое и было и остается без явного разжовывания.
QUOTE
Это было бы справедливо, если бы какие-нибудь из древних компиляторов считали while(const) ошибкой. Есть такие?

Я как-бы НИКОГДА не писал по причине нахренненужнсти while(const), так-что когда они были действително старые, то не сталкивался. Ну а потом, когда уже из интернету хлынул поток c таким, то warning были, поскольку всегда все по максимуму поднимаю.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 29 2015, 23:04
Сообщение #94


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Aug 29 2015, 22:39) *
Не сочтите за труд ознакомится с ранее данным ответом на этот вопрос.

По ключевому вопросу whille (const) всё прояснилось. Остальное не интересно. Превращать ремарки в варнинги и пугать народ не надо.

Цитата(zltigo @ Aug 29 2015, 22:39) *
Частные случаи на то и частные, что не всегда эквиваленты общим. По этой причне в стандарте эти понятия и РАЗДЕЛЕНЫ и constant expression в контесте while() НЕ упоминаются, в отличие, кстати, от for()

Вхождение во множество частного случая не обязано упоминаться. Упоминаются только исключения частных случаев. Для ограничения множества (выражений) в каком-то типе цикла нужно это явно описывать с обоснованием. Т.к. в цикле for все три аргумента независимы друг от друга, то управляющее выражение ничем не должно отличаться от других циклов. Но, судя по всему, в стандарте оно отличается тем, что отсутствие выражения в нём принимается за истину. И это странно, во-первых из-за нарушения симметрии. Не читал стандарт, но возможно необоснованного. Кроме того, отсутствие чего-то логичнее принимать за 0.

Упд.
Похоже на за уши притягивание этого типа цикла к бесконечным.

Сообщение отредактировал GetSmart - Aug 30 2015, 10:03


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 30 2015, 07:03
Сообщение #95


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (GetSmart @ Aug 30 2015, 02:04) *
Превращать ремарки в варнинги и пугать народ не надо.

Деление на ремарки и варнинги весьма условное и не у всех компиляторов. У MS нет: https://msdn.microsoft.com/en-us/library/6t...h(v=vs.90).aspx
А у некоторых нет ни того ни другого они пишут "Diagnostic 279: controlling expression is constant".


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 30 2015, 08:53
Сообщение #96


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (aaarrr @ Aug 29 2015, 19:07) *
Препроцессор тут с визгом притянут за уши. Это не аргумент. Совсем.

А вот такой случай из жизни (специально нашел в интернете, а не сочинил, дабы не выслушивать глупости про уши):
http://www.codeexplain.com/code/253778d0-3...c1-57064dc5a918
Явно БЕССМЫСЛЕННОЕ выражение возникшее в результате ошибки было молча проглочено GCC. А MS предупредил-бы, что ему подозрительно. Вот о озадачился автор, как включить сие предупреждение, ну а ему рассказали что не понимает он своего счастья от отсутствия предупреждения sm.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
gerber
сообщение Aug 30 2015, 09:34
Сообщение #97


Знающий
****

Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088



Цитата(zltigo @ Aug 28 2015, 22:05) *
for(;;)
Это есть цикл без проверки условия, а не цикл с проверкой того, что измениться не может.
Неадекватным оно было-бы в виде for( ; 1 ; )

В операторе for есть 3 выражения, цикл выполняется, если значение 2-го выражения отлично от нуля. В этом ракурсе вовсе неочевидно, что в случае for(;;) проверки условия не будет вообще - будет проверка значения пустого оператора. И уж совсем неочевидно, что значение пустого оператора отлично от нуля. biggrin.gif

Сообщение отредактировал gerber - Aug 30 2015, 09:35


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 30 2015, 10:01
Сообщение #98


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (gerber @ Aug 30 2015, 12:34) *
В операторе for есть 3 выражения, цикл выполняется, если значение 2-го выражения отлично от нуля. В этом ракурсе вовсе неочевидно, что в случае for(;;) проверки условия не будет вообще - будет проверка значения пустого оператора. И уж совсем неочевидно, что значение пустого оператора отлично от нуля. biggrin.gif

Очень жаль, что Деннис Ритчи умер, а то Вы могли-бы попробовать "доказать" ему, что он не прав. Но есть рабочая группа по стандарту языка - обраьтиесь туда со своми трактовкам и НОВЕЙШЕЙ терминологией. Мне "доказывать" не надо, поскольку:
Во-первых, мне все понятно в for( ; ; ), поскольку и в русском и английском есть такое слово "безусловно/unconditionally", котороое описывает и данную ситуацию - ОТСУТСТВИЯ условия.
Во-вторых я не могу изменить стандарт.



--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 30 2015, 10:11
Сообщение #99


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Aug 30 2015, 11:03) *
Деление на ремарки и варнинги весьма условное и не у всех компиляторов.

....

Вот о озадачился автор, как включить сие предупреждение,...

Ремарка это скорее подсказка. Качество кода подсказками не измеряется.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 30 2015, 10:17
Сообщение #100


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (GetSmart @ Aug 30 2015, 13:11) *
Ремарка это скорее подсказка. Качество кода подсказками не измеряется.

Это Вы себя пытаетесь убедить повторяя одно и то-же? Тогда можете продолжать. Меня не удастся, по причине уже дважды озвученной ранее: http://electronix.ru/forum/index.php?showt...t&p=1361385
И в приведенном прмере http://electronix.ru/forum/index.php?showt...t&p=1361385 отсутствующая "подсказка" оказалось ПРОПУЩЕННОЙ ошибкой. Ошибки тоже никак на качество кода не влияют? Так-что все, с этим закончили. Можете сколь угодно долго в самооправдание продолжать долдонить " Качество кода подсказками не измеряется".


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

18 страниц V   1 2 3 > » 
Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 18:39
Рейтинг@Mail.ru


Страница сгенерированна за 0.02786 секунд с 7
ELECTRONIX ©2004-2016