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

 
 
18 страниц V  < 1 2 3 4 5 > »   
Reply to this topicStart new topic
> Косяк у Кейла, Препроцессор не следит за скобками
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

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 16:08
Рейтинг@Mail.ru


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