Перейти к содержанию
    

Огласите пожалуйста решение лучше. Думаю многим было бы интересно на него посмотреть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Изменено пользователем Mihey_K

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Огласите пожалуйста решение лучше. Думаю многим было бы интересно на него посмотреть.

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

 

 

Бессмысленной можно было бы признать запись while(0) {...} - тут warning был бы вполне уместен

Бессмысленнен любой с константой.

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

Нет смысла и в этом, ибо для одной итерации достаточно {....}

Так-что весь этот трюк из-за ";" и не для чего более.

 

там почти все макросы переносом строки,

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

проблематичен при использовании типа такого:

if( )

MACRO();

 

Посему либо следить за тем, что-бы:

if()

{

MACRO();

}

либо трюк использовать,

 

Либо только {}, но тогда так

if()

MACRO()

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему-то думал, что ViKo - бывалый. А он в таких азах плавает :laughing:

Думал, раз первое действие - с ULL числами, то препроцессор "запомнит", с чем имеет дело. А дальше искал, где же оно переполняется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вообще то, насколько я помню трюк

do

while(0)

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

 

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

 

while(1), while(0) имеет тот же смысл что описан в стандарте, никаких конструкций и правил он не нарушает, потому имеет право на жизнь и использование в тексте, ровно как и

for(;;). Наличие или отсутствие варнинга - это на усмотрение среды, ибо любые варнинги - это предупреждения от пользователя о возможных ошибках. И тут нет вопроса забили или не забили. Просто все посчитали что доставать пользователя таким варнингом излишне...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Бессмысленнен любой с константой.

Тогда и любимый Вами for(;;) столь же бессмысленнен, т.к. по сути цикл с константой в управляющем выражении.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Думал, раз первое действие - с ULL числами, то препроцессор "запомнит", с чем имеет дело. А дальше искал, где же оно переполняется.

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

 

Тогда и любимый Вами for(;;) столь же бессмысленнен, т.к. по сути цикл с константой в управляющем выражении.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

напишите for ( ; true; ), если пустота не нравится. :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сначала любые операнды типа 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 и что-бы они ни было, по мне оно звучит странно.... я в чем то не прав?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда и любимый Вами for(;;) столь же бессмысленнен, т.к. по сути цикл с константой в управляющем выражении.

АБСОЛЮТНО адекватное выражение и по этой причине является официально-страндартым вариантом для бесконечного цикла.

Это есть цикл без проверки условия, а не цикл с проверкой того, что измениться не может.

Неадекватным оно было-бы в виде for( ; 1 ; )

 

 

 

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это есть цикл без проверки условия, а не цикл с проверкой того, что измениться не может.

Да ну! А в стандарте написано, что опущенное управляющее выражение заменяется ненулевой константой:

An omittedexpression-2is replaced by a nonzero constant.

 

То есть неявно превращается в "цикл с проверкой того, что измениться не может".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да это вообще абракадабра.

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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) - это нормально

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...