|
|
  |
Косяк у Кейла, Препроцессор не следит за скобками |
|
|
|
Aug 28 2015, 16:17
|

Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Aug 28 2015, 17:22
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
вообще то, насколько я помню трюк do while(0) создан для того чтобы в теле можно было в любой момент поставить break или continue и вывалиться из цикла, то есть закончить кусок кода без применения нелюбимого и кое где запрещенного оператора goto. Интересное использование в качестве превращение группы операторов в один, чтобы он под условие влезал без скобок...
символ переноса строки используется для переноса строки без ее разрыва. Дефайн требует объявление в 1 строку, а от этого падает читаемость. Но думая про то что много строк - это обычно надо для множества операторов, то может правило все пихать сразу под ду-вайл(0) для универсальности макроса может и имеет смысл....
while(1), while(0) имеет тот же смысл что описан в стандарте, никаких конструкций и правил он не нарушает, потому имеет право на жизнь и использование в тексте, ровно как и for(;;). Наличие или отсутствие варнинга - это на усмотрение среды, ибо любые варнинги - это предупреждения от пользователя о возможных ошибках. И тут нет вопроса забили или не забили. Просто все посчитали что доставать пользователя таким варнингом излишне...
|
|
|
|
|
Aug 28 2015, 17:39
|
Гуру
     
Группа: Свой
Сообщений: 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 (;;)", но это дело вкуса...
|
|
|
|
|
Aug 28 2015, 18:01
|
Гуру
     
Группа: Свой
Сообщений: 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 и что-бы они ни было, по мне оно звучит странно.... я в чем то не прав?
|
|
|
|
|
Aug 28 2015, 18:05
|

Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Aug 28 2015, 18:06
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(zltigo @ Aug 28 2015, 21:03)  Это есть цикл без проверки условия, а не цикл с проверкой того, что измениться не может. Да ну! А в стандарте написано, что опущенное управляющее выражение заменяется ненулевой константой: Цитата An omittedexpression-2is replaced by a nonzero constant. То есть неявно превращается в "цикл с проверкой того, что измениться не может".
|
|
|
|
|
Aug 28 2015, 18:11
|
Гуру
     
Группа: Свой
Сообщений: 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) - это нормально
|
|
|
|
|
  |
5 чел. читают эту тему (гостей: 5, скрытых пользователей: 0)
Пользователей: 0
|
|
|