Re: #define
От: ononim  
Дата: 09.02.11 15:58
Оценка: 1 (1)
NS>Вылазит ошибка, что проблема в макросе, где я ошибся?
ошибка в том, что ваш макрос при вставке разворачивается в такой вот некомпиляемый код:

int i = 4; 
.Foo(( if(i > 0) i = 9; ));  // вызов

а как делать правильно — вам уже написали
Как много веселых ребят, и все делают велосипед...
Re[5]: #define
От: uzhas Ниоткуда  
Дата: 09.02.11 21:18
Оценка: 1 (1)
Здравствуйте, Енот-полоскун, Вы писали:

ЕП>Приоритет у тернарной операции выше, чем у присваивания. Так что тогда уж так:


ЕП>
ЕП>inline
ЕП>int NormalizeX(int& x)
ЕП>{
ЕП>  return x > 0 ? (x = 9) : x;
ЕП>}
ЕП>


тут приоритеты неважны, присваивание будет сделано только в том случае, если x > 0 и приоритет = ни играет никакой роли
приоритеты играют в других случаях:
http://codepad.org/uRVjVqpU
Re: #define
От: uzhas Ниоткуда  
Дата: 09.02.11 13:20
Оценка: +1
Здравствуйте, NordSky, Вы писали:

NS>Хочу сделать так:


NS>
NS>#define ACTION(x) (\
NS> if(x > 0) x = 9; \
NS>)
NS>



NS>Пытаюсь использовать вот так


NS>
NS>void Foo(int i);  // прототип

NS>int i = 4; 
NS>.Foo(ACTION(i));  // вызов
NS>





NS>Вылазит ошибка, что проблема в макросе, где я ошибся?

в макросе нужно написать выражение. которые будет спокойно преобразовываться в int (аргумент функции Foo)
у вас нет такого выражения в макросе
там написано

if (x>0) x = 9;

у него нет целочисленного значения, это просто стейтменты
могу порекомендовать такое:
int Action(int& x)
{
  return x > 0 ? x = 9 : x;
}
void Foo(int i);
int i = 4;
Foo(Action(i));
Re[4]: #define
От: Енот-полоскун  
Дата: 09.02.11 15:22
Оценка: -1
Здравствуйте, chemey, Вы писали:

C>
C>inline
C>int Action(int& x)
C>{
C>  return x > 0 ? x = 9 : x;
C>}
C>


Приоритет у тернарной операции выше, чем у присваивания. Так что тогда уж так:

inline
int NormalizeX(int& x)
{
  return x > 0 ? (x = 9) : x;
}
Re[4]: #define
От: Masterkent  
Дата: 10.02.11 11:42
Оценка: +1
winston:

W>>>#define ACTION(x) (x > 0 ? x = 9 : x)


C>>Если писать макрос, то писать правильно:


C>>
#define ACTION(x) ((x) > 0 ? (x) = 9 : (x))


W>И в чем тут правильность? Кроме переменной макрос все равно ничего не примет, так что скобками обрамлять не имеет смысла, мне кажется.


Попробуй на место x подставить выражение вида a ? b : c. В случае применения исходного варианта получится

( a ? b : c > 0 ? a ? b : c = 9 : a ? b : c )

что эквивалентно

( (a ? b : (c > 0)) ? a ? b : (c = 9) : (a ? b : c) )

В случае применения варианта со скобками получится

( (a ? b : c) > 0 ? (a ? b : c) = 9 : (a ? b : c) )

что эквивалентно

( ((a ? b : c) > 0) ? (a ? b : c) = 9 : (a ? b : c) )

В последнем операнде разницы нет, зато в первом и втором она вполне заметна.
#define
От: NordSky Россия  
Дата: 09.02.11 13:16
Оценка:
Хочу сделать так:

#define ACTION(x) (\
 if(x > 0) x = 9; \
)



Пытаюсь использовать вот так

void Foo(int i);  // прототип

int i = 4; 
.Foo(ACTION(i));  // вызов





Вылазит ошибка, что проблема в макросе, где я ошибся?
Re[2]: #define
От: NordSky Россия  
Дата: 09.02.11 13:27
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, NordSky, Вы писали:


NS>>Хочу сделать так:


NS>>
NS>>#define ACTION(x) (\
NS>> if(x > 0) x = 9; \
NS>>)
NS>>



NS>>Пытаюсь использовать вот так


NS>>
NS>>void Foo(int i);  // прототип

NS>>int i = 4; 
NS>>.Foo(ACTION(i));  // вызов
NS>>





NS>>Вылазит ошибка, что проблема в макросе, где я ошибся?

U>в макросе нужно написать выражение. которые будет спокойно преобразовываться в int (аргумент функции Foo)
U>у вас нет такого выражения в макросе
U>там написано
U>

if (x>0) x = 9;

U>у него нет целочисленного значения, это просто стейтменты
U>могу порекомендовать такое:
U>
U>int Action(int& x)
U>{
U>  return x > 0 ? x = 9 : x;
U>}
U>void Foo(int i);
U>int i = 4;
U>Foo(Action(i));
U>


Хотелось,конечно,без вызова функции обойтись, но придется скорее всего, спасибо
Re: #define
От: winston Россия  
Дата: 09.02.11 13:35
Оценка:
Здравствуйте, NordSky, Вы писали:

NS>Хочу сделать так:


NS>
NS>#define ACTION(x) (\
NS> if(x > 0) x = 9; \
NS>)
NS>



NS>Пытаюсь использовать вот так


NS>
NS>void Foo(int i);  // прототип

NS>int i = 4; 
NS>.Foo(ACTION(i));  // вызов
NS>





NS>Вылазит ошибка, что проблема в макросе, где я ошибся?


#define ACTION(x) (x > 0 ? x = 9 : x)
Re[3]: #define
От: chemey  
Дата: 09.02.11 13:43
Оценка:
Здравствуйте, NordSky, Вы писали:

NS>Хотелось,конечно,без вызова функции обойтись, но придется скорее всего, спасибо


Дыкть:

inline
int Action(int& x)
{
  return x > 0 ? x = 9 : x;
}
Бзззззззжжжжж
Re[2]: #define
От: Centaur Россия  
Дата: 10.02.11 07:22
Оценка:
Здравствуйте, winston, Вы писали:

NS>>Вылазит ошибка, что проблема в макросе, где я ошибся?


W>#define ACTION(x) (x > 0 ? x = 9 : x)


Если писать макрос, то писать правильно:

#define ACTION(x) ((x) > 0 ? (x) = 9 : (x))
Re[3]: #define
От: winston Россия  
Дата: 10.02.11 07:42
Оценка:
Здравствуйте, Centaur, Вы писали:

C>Здравствуйте, winston, Вы писали:


NS>>>Вылазит ошибка, что проблема в макросе, где я ошибся?


W>>#define ACTION(x) (x > 0 ? x = 9 : x)


C>Если писать макрос, то писать правильно:


C>
#define ACTION(x) ((x) > 0 ? (x) = 9 : (x))


И в чем тут правильность? Кроме переменной макрос все равно ничего не примет, так что скобками обрамлять не имеет смысла, мне кажется. Или Вы про что?
Re[6]: #define
От: uzhas Ниоткуда  
Дата: 10.02.11 10:45
Оценка:
Здравствуйте, uzhas, Вы писали:

U>приоритеты играют в других случаях:

U>http://codepad.org/uRVjVqpU
здесь я ошибся , неправильный пример, показывающий важность приоритетов
подтверждение: http://codepad.org/fFSPGTB7
здесь скорее всего играет жадный парсер
Re[5]: #define
От: Masterkent  
Дата: 10.02.11 11:39
Оценка:
Енот-полоскун:

C>>
C>>inline
C>>int Action(int& x)
C>>{
C>>  return x > 0 ? x = 9 : x;
C>>}
C>>


ЕП>Приоритет у тернарной операции выше, чем у присваивания.


У тернарного оператора приоритет и ассоциативность такие же, как и у оператора присваивания, причём применяются они только в отношении левого и правого операндов. В качестве среднего операнда может выступать выражение любой синтаксической формы (тут действуют только семантические ограничения).
Re[4]: #define
От: jyuyjiyuijyu  
Дата: 10.02.11 11:57
Оценка:
Здравствуйте, winston, Вы писали:

W>Здравствуйте, Centaur, Вы писали:


C>>Здравствуйте, winston, Вы писали:


NS>>>>Вылазит ошибка, что проблема в макросе, где я ошибся?


W>>>#define ACTION(x) (x > 0 ? x = 9 : x)


C>>Если писать макрос, то писать правильно:


C>>
#define ACTION(x) ((x) > 0 ? (x) = 9 : (x))


W>И в чем тут правильность? Кроме переменной макрос все равно ничего не примет, так что скобками обрамлять не имеет смысла, мне кажется. Или Вы про что?

только в скобочки потому что в выражении где будет использоватся этот макрос тернарный оператор имеет мньший приоритет и трактуется иначе чем вызов функции по сути неделимой операции в отлчии от того же ?: которого если не взять в скобочки можно получить черти что вы хотите обманчивую семаентику ? вы будете видет вызов функции надеятся на семантику и поведение вызова функции а получите косяки тернарного оператора если все эито дело не взять в сакобочки насчет взять аргумекнт макроса в скобочки это только повысит наглядность не надо голову ломать в каких синтаксических конструкциях это приведет к багу если не взять например в чмстом си смысла брать нету в в си++ есть так аргуент сам может быть тернарный оператор к примеру результат которого используется как lvalue
Re[5]: #define
От: jyuyjiyuijyu  
Дата: 10.02.11 12:03
Оценка:
конечно для чистого си брать в скобочки не имеет смысла там просто недопустим тернарный оператор как lvalue на чистого си имеет смысл взять в скобочки только все тело макроса
а вообще это бажный код какой то если полагается на это отличие в семантике лучше на сипипи так не писать ну всмысле не использовать результат тернарного как lvalue православный сишник этого не поймет и не сможет даже скомпилить
вот нафига было так менять поведение в сипипи ????? нельзя что ли было оставить как в си при переходе к сипипи думаеш знаеш семантику а потом спотыкаешся на такой фигне
Re[5]: #define
От: winston Россия  
Дата: 10.02.11 12:05
Оценка:
Здравствуйте, Masterkent, Вы писали:

Понял, спасибо за разъяснения, че то сразу не подумал о передаче самой тернарной операции в макрос, действительно без скобок плохо получится.
Re[6]: #define
От: jyuyjiyuijyu  
Дата: 10.02.11 12:22
Оценка:
тда и не только есть еще баги если ка сипипи компилить опять же если передать тернарный оператор то получится
((x) > 0 ? (x) = 9 : (x))

(a) ? (b) : ((c > 0) ? (a ? b : c = 9) : (a ? b : c))
что выражение вообще считатся не будет
а православный си не скомпилит споткнется не из за первого выражения а из за присваивания результату ?:
вывод в си ненадо брать в скобки это просто не скомпилится а в сипипи если не взять целых две ловушки получитя в разных местах
Re[5]: #define
От: jyuyjiyuijyu  
Дата: 10.02.11 12:41
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>winston:


W>>>>#define ACTION(x) (x > 0 ? x = 9 : x)


C>>>Если писать макрос, то писать правильно:


C>>>
#define ACTION(x) ((x) > 0 ? (x) = 9 : (x))


W>>И в чем тут правильность? Кроме переменной макрос все равно ничего не примет, так что скобками обрамлять не имеет смысла, мне кажется.


M>Попробуй на место x подставить выражение вида a ? b : c. В случае применения исходного варианта получится


M>
( a ? b : c > 0 ? a ? b : c = 9 : a ? b : c )

M>что эквивалентно

M>
( (a ? b : (c > 0)) ? a ? b : (c = 9) : (a ? b : c) )


неправда вашаъ
( a ? b : c > 0 ? a ? b : c = 9 : a ? b : c )
не эквивалентно
( (a ? b : (c > 0)) ? a ? b : (c = 9) : (a ? b : c) )
а эквивалентноъ
( (a) ? (b) : ((c > 0) ? (a ? b : c = 9) : (a ? b : c))
Re[5]: #define
От: Masterkent  
Дата: 10.02.11 12:51
Оценка:
Masterkent:

M>
( a ? b : c > 0 ? a ? b : c = 9 : a ? b : c )

M>что эквивалентно

M>
( (a ? b : (c > 0)) ? a ? b : (c = 9) : (a ? b : c) )

Неправильно скобочки поставил Правильно будет так:

( a ? b : ( (c > 0) ? a ? b : (c = 9) : (a ? b : c) ) )
Re[6]: #define
От: jyuyjiyuijyu  
Дата: 10.02.11 13:35
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>Енот-полоскун:


C>>>
C>>>inline
C>>>int Action(int& x)
C>>>{
C>>>  return x > 0 ? x = 9 : x;
C>>>}
C>>>


ЕП>>Приоритет у тернарной операции выше, чем у присваивания.


M>У тернарного оператора приоритет и ассоциативность такие же, как и у оператора присваивания, причём применяются они только в отношении левого и правого операндов. В качестве среднего операнда может выступать выражение любой синтаксической формы (тут действуют только семантические ограничения).

не такие же а у = ниже а у ?: выше иначе бы это работало не правильно
var += cond ? expr : expr;
если бы были такие же то условие было бы (var += cond) ? а реально только (cond)
а почему в третьем выражении присваивание входит в третье выражение читайте ниже

The binding of operators in C and C++ is specified (in the corresponding Standards) by a factored language grammar, rather than a precedence table. This creates some subtle conflicts. For example, in C, the syntax for a conditional expression is:
logical-OR-expression ? expression :
conditional-expression

while in C++ it is:
logical-or-expression ? expression :
assignment-expression

Hence, the expression:
e = a ? b : c = d

is parsed differently in the two languages. In C, this expression is parsed as:
e = ((a ? b : c) = d)

which is a semantic error, since the result of a conditional-expression is not an lvalue. In C++, it is parsed as:
e = (a ? b : (c = d))

which is a valid expression.

Re[7]: #define
От: Masterkent  
Дата: 10.02.11 14:15
Оценка:
jyuyjiyuijyu:

ЕП>>>Приоритет у тернарной операции выше, чем у присваивания.


M>>У тернарного оператора приоритет и ассоциативность такие же, как и у оператора присваивания, причём применяются они только в отношении левого и правого операндов. В качестве среднего операнда может выступать выражение любой синтаксической формы (тут действуют только семантические ограничения).

J>не такие же а у = ниже а у ?: выше

В C — возможно (ХЗ, я им почти не интересуюсь), в C++ — нет.

J>иначе бы это работало не правильно

J>var += cond ? expr : expr;
J>если бы были такие же то условие было бы (var += cond) ?

С чего бы это, если речь идёт о правоассоциативных операторах? У правоассоциативного оператора правый операнд может быть результатом применения (без обрамляющих скобок) оператора с таким же приоритетом, а левый операнд — не может.
Re[8]: #define
От: jyuyjiyuijyu  
Дата: 10.02.11 15:26
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>jyuyjiyuijyu:


ЕП>>>>Приоритет у тернарной операции выше, чем у присваивания.


M>>>У тернарного оператора приоритет и ассоциативность такие же, как и у оператора присваивания, причём применяются они только в отношении левого и правого операндов. В качестве среднего операнда может выступать выражение любой синтаксической формы (тут действуют только семантические ограничения).

J>>не такие же а у = ниже а у ?: выше

M>В C — возможно (ХЗ, я им почти не интересуюсь), в C++ — нет.


J>>иначе бы это работало не правильно

J>>var += cond ? expr : expr;
J>>если бы были такие же то условие было бы (var += cond) ?

M>С чего бы это, если речь идёт о правоассоциативных операторах? У правоассоциативного оператора правый операнд может быть результатом применения (без обрамляющих скобок) оператора с таким же приоритетом, а левый операнд — не может.

"Язык программирования C++ специальное издание"
во первых приоритет у них разный

--------------------
||
--------------------
expr ? expr : expr
--------------------
= ...
--------------------

теперь тернарный оператор

Несколько грамматических правил нельзя выразить
в терминах приоритетов (называемых также силой связывания)
и ассоциативности. Например, a=b<c ? d=e : f=g
означает a=((b<c) ? (d=e) : (f=g)), но для того чтобы об этом
догадатся, нужно обратиться к правилам грамматики

так о какой ассоциативности вы говорите в данном случае ?
вот имекнно тут надо смотреть грамматику смотрим

logical-or-expression ? expression :
assignment-expression

теперь ясно почему в третье выражение входит присваивание
в отличии от того же си где оно не входит

logical-OR-expression ? expression :
conditional-expression

--

Унарные операторы и операторы присваивания правоассоциативны,
а все остальные левоассоциативны.

все что вы тут говорите про ассоциативность это не более чем бред
Re[9]: #define
От: blackhearted Украина  
Дата: 10.02.11 16:00
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>Здравствуйте, Masterkent, Вы писали:


M>>jyuyjiyuijyu:


ЕП>>>>>Приоритет у тернарной операции выше, чем у присваивания.


M>>>>У тернарного оператора приоритет и ассоциативность такие же, как и у оператора присваивания, причём применяются они только в отношении левого и правого операндов. В качестве среднего операнда может выступать выражение любой синтаксической формы (тут действуют только семантические ограничения).

J>>>не такие же а у = ниже а у ?: выше

M>>В C — возможно (ХЗ, я им почти не интересуюсь), в C++ — нет.


J>>>иначе бы это работало не правильно

J>>>var += cond ? expr : expr;
J>>>если бы были такие же то условие было бы (var += cond) ?

M>>С чего бы это, если речь идёт о правоассоциативных операторах? У правоассоциативного оператора правый операнд может быть результатом применения (без обрамляющих скобок) оператора с таким же приоритетом, а левый операнд — не может.

J>"Язык программирования C++ специальное издание"
дядька Шилдт ?
Re[10]: #define
От: jyuyjiyuijyu  
Дата: 10.02.11 16:42
Оценка:
Здравствуйте, blackhearted, Вы писали:

B>дядька Шилдт ?

http://www.rsdn.ru/res/book/cpp/cpp_bible.xml
Автор(ы): Бьерн Страуструп
Книга написана Бьёрном Страуструпом — автором языка программирования С++ — и является каноническим изложением возможностей этого языка. Помимо подробного описания собственно языка, на страницах книги вы найдете доказавшие свою эффективность подходы к решению разнообразных задач проектирования и программирования. Многочисленные примеры демонстрируют как хороший стиль программирования на С-совместимом ядре С++, так и современный объектно-ориентированный подход к созданию программных продуктов. Третье издание бестселлера было существенно переработано автором. Результатом этой переработки стала большая доступность книги для новичков. В то же время, текст обогатился сведениями и методиками программирования, которые могут оказаться полезными даже для многоопытных специалистов по С++. Не обойдены вниманием и нововведения языка: стандартная библиотека шаблонов (STL), пространства имен (namespaces), механизм идентификации типов во время выполнения (RTTI), явные приведения типов (cast-операторы) и другие. Настоящее специальное издание отличается от третьего добавлением двух новых приложений (посвященных локализации и безопасной обработке исключений средствами стандартной библиотеки), довольно многочисленными уточнениями в остальном тексте, а также исправлением множества опечаток. Книга адресована программистам, использующим в своей повседневной работе С++. Она также будет полезна преподавателям, студентам и всем, кто хочет ознакомиться с описанием языка «из первых рук».
Re[9]: #define
От: Masterkent  
Дата: 10.02.11 17:56
Оценка:
jyuyjiyuijyu:

J>"Язык программирования C++ специальное издание"

J>во первых приоритет у них разный
J>

J>--------------------
J>||
J>--------------------
J>expr ? expr : expr
J>--------------------
J>= ...
J>--------------------

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

simple assignment           lvalue = expr
multiply and assign         lvalue *= expr
divide and assign           lvalue /= expr
modulo and assign           lvalue %= expr
add and assign              lvalue += expr
subtract and assign         lvalue = expr
shift left and assign       lvalue <<= expr
shift right and assign      lvalue >>= expr
AND and assign              lvalue &= expr
inclusive OR and assign     lvalue |= expr
exclusive OR and assign     lvalue ^= expr
----------------------------------------------
conditional expression      expr ? expr : expr
----------------------------------------------
throw exception             throw expr

Уже смешно. Во-вторых, из стандарта C++ следует другое соотношение приоритетов, а именно: приоритет тернарного оператора, операторов группы присваивания и throw один и тот же.

J>теперь тернарный оператор

J>

J>Несколько грамматических правил нельзя выразить
J>в терминах приоритетов (называемых также силой связывания)
J>и ассоциативности.

Грамматические правила C++ в отношении тернарного оператора вполне хорошо описываются в терминах приоритетов и ассоциативности. Если Страуструп не смог додуматься до способа описания, это его личные проблемы.

J>так о какой ассоциативности вы говорите в данном случае ?


О такой же, как у бинарных операторов — при условии, что средний операнд ?: мы не рассматриваем. Нерассмотрение операнда в данном случае не является чем-то совершенно исключительным. Операнды typeid и всех .._cast преобразований, а также операнд операции индексации, заключённый в [], могут представлять собой выражения произвольной корректной синтаксической формы, и применять к ним понятия приоритетов и ассоциативности бессмысленно.

J>вот имекнно тут надо смотреть грамматику


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

J>все что вы тут говорите про ассоциативность это не более чем бред


Чтобы доказать это, тебе нужно привести хотя бы один пример, когда с помощью правил ассоциативности невозможно достоверно выяснить расположение операндов в выражении, состоящем только из операторов группы присваивания, тернарного оператора и throw.

Отдельное замечание о throw. Если бы приоритет throw был ниже, чем у ?:, то следующую запись

0 ? 0 : throw 0;

надо было бы считать синтаксически некорректной. Выражение throw 0 не может быть использовано в качестве операнда, учитываемого при применении правил приоритетов и ассоциативности, у операции с более высоким приоритетом. В частности, выражение (void)throw 0 синтаксически некорректно (приоритет операции преобразования типа в cast-нотации выше, чем у throw).
Re[10]: #define
От: jyuyjiyuijyu  
Дата: 10.02.11 21:18
Оценка:
Здравствуйте, Masterkent, Вы писали:

---
приоритет нигде не нарушается
а странности с ?: объясняются грамматикой
поэтому можно и throw и = хотя они ниже приоритетом

logical-OR-expression ? expression : assignment-expression

assignment-expression:
conditional-expression
logical-or-expression assignment-operator assignment-expression
throw-expression
Re[11]: #define
От: Masterkent  
Дата: 11.02.11 05:59
Оценка:
jyuyjiyuijyu:

J>---

J>приоритет нигде не нарушается

Я не понял, о чём тут идёт речь.

J>а странности с ?:


Он не более странный, чем, скажем, оператор new, у которого вообще нет операндов, на которые бы распространялись правила приоритетов и ассоциативности.

J>объясняются грамматикой


Расположение операндов любых операторов можно объяснить, пользуясь правилами грамматики. Для меня это не новость.

J>поэтому можно и throw и = хотя они ниже приоритетом


Будь они ниже приоритетом, нам пришлось бы

1) согласиться с тем, что a ? b : c = d эквивалентно (a ? b : c) = d (вместо a ? b : (c = d) — как оно есть на самом деле) и a ? b : throw c синтаксически некорректно (что в действительности не так), либо

2) исключить правый операнд ?: из рассмотрения (но тогда с тем же успехом можно исключить из рассмотрения правый операнд = и считать, что выражения вроде a = b = c невозможно разобрать, основываясь на приоритете и ассоциативности), но остаётся непонятным, зачем вводить подобные искусственные ограничения, если можно сразу выбрать другие приоритеты, при которых рассмотрение как левого, так и правого операндов ?: не сопряжено с какими-либо проблемами.
Re[12]: #define
От: jyuyjiyuijyu  
Дата: 11.02.11 09:48
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>jyuyjiyuijyu:


M>Будь они ниже приоритетом, нам пришлось бы


M>1) согласиться с тем, что a ? b : c = d эквивалентно (a ? b : c) = d

так оно и есть Страуструп не зря
про это пишет

Несколько грамматических правил нельзя выразить
в терминах приоритетов (называемых также силой связывания)
и ассоциативности. Например, a=b<c ? d=e : f=g
означает a=((b<c) ? (d=e) : (f=g)), но для того чтобы об этом
догадатся, нужно обратиться к правилам грамматики

иначе зачем бы он вообще это написал как вы думаете
если все ясно из приоритетов и ассоциативности ?
Re[12]: #define
От: jyuyjiyuijyu  
Дата: 11.02.11 09:56
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>2) исключить правый операнд ?: из рассмотрения (но тогда с тем же успехом можно исключить из рассмотрения правый операнд = и считать, что выражения вроде a = b = c невозможно разобрать, основываясь на приоритете и ассоциативности)

a = b = c
что тут не понятно ?
зачем исключать операнды ?
вы какой то бред пишите
в тернарном мы исключаем оператор а тут вы пишите про исключение операнда
здесь как раз все прекрасно разбирается из приоритета и ассоциативности
Re[12]: #define
От: jyuyjiyuijyu  
Дата: 11.02.11 10:29
Оценка:
Здравствуйте, Masterkent, Вы писали:

---
вот кстати таблица приоритетов для msvc++ 2010
присваивание имеет меньший приоритет
чем тернарный оператор
http://msdn.microsoft.com/ru-ru/library/126fe14k.aspx
там это четко разделено
Re[12]: #define
От: jyuyjiyuijyu  
Дата: 11.02.11 10:40
Оценка:
Здравствуйте, Masterkent, Вы писали:

---
в си и сипипи не изменился приоритет присваивания и тернарного
оператора изменилась грамматика у сипипи
как он в си был ниже приоритетом так и в сипипи
просто трактоватся в силу изменения грамматики стал иначе
в тернарном операторе
Re[13]: #define
От: Masterkent  
Дата: 11.02.11 11:27
Оценка:
jyuyjiyuijyu:

M>>Будь они ниже приоритетом, нам пришлось бы


M>>1) согласиться с тем, что a ? b : c = d эквивалентно (a ? b : c) = d

J>так оно и есть

В C++ — нет. Посмотри хотя бы в свою же цитату из книжонки Страуструпа.

J>Страуструп не зря

J>про это пишет
J>

J>Несколько грамматических правил нельзя выразить
J>в терминах приоритетов (называемых также силой связывания)
J>и ассоциативности. Например, a=b<c ? d=e : f=g
J>означает a=((b<c) ? (d=e) : (f=g)), но для того чтобы об этом
J>догадатся, нужно обратиться к правилам грамматики

Разбор данного примера мало чем отличается от

a = b < c += f = g

Тут приоритет < выше, чем у += и =, и, стало быть, b < c является отдельным операндом.

a = (b < c) += f = g

Далее для операндов операторов = и += (имеющих равный приоритет) применяется правило ассоциативности. Поскольку данные операторы правоассоциативны, их группировка происходит справа налево, т.е. выражение f = g выступает в качестве правого операнда оператора +=, а выражение b < c += f = g выступает в качестве правого операнда левого оператора =. В итоге получается следующая группировка:

a = ((b < c) += (f = g))

Теперь рассмотрим

a = b < c ? d = e : f = g

Для начала мысленно уберём операнд d = e, к которому правила приоритетов и ассоциативности не применяются:

a = b < c ?: f = g

Далее применяем те же рассуждения, что и для примера с оператором +=. Получаем:

a = ((b < c) ?: (f = g))

Остаётся лишь вернуть d = e на место — в итоге получится:

a = ((b < c) ? d = e : (f = g))

Это соответствует правильной группировке операторов? Да, соответствует. Так в чём тогда проблема?

J>иначе зачем бы он вообще это написал как вы думаете

J>если все ясно из приоритетов и ассоциативности ?

Это тебе надо у Страуструпа спрашивать, зачем он такое написал.
Re[13]: #define
От: Masterkent  
Дата: 11.02.11 11:34
Оценка:
jyuyjiyuijyu:

J>---

J>вот кстати таблица приоритетов для msvc++ 2010
J>присваивание имеет меньший приоритет
J>чем тернарный оператор
J>http://msdn.microsoft.com/ru-ru/library/126fe14k.aspx
J>там это четко разделено

Поздравляю: ты нашёл ещё одну плохую таблицу приоритетов.
Re[13]: #define
От: Masterkent  
Дата: 11.02.11 12:08
Оценка:
jyuyjiyuijyu:

M>>2) исключить правый операнд ?: из рассмотрения (но тогда с тем же успехом можно исключить из рассмотрения правый операнд = и считать, что выражения вроде a = b = c невозможно разобрать, основываясь на приоритете и ассоциативности)

J>a = b = c
J>что тут не понятно ?
J>зачем исключать операнды ?

Я привёл сравнение ?: с оператором =. Как и у оператора присваивания, у тернарного оператора имеются левый и правый операнды. Исключив из рассмотрения средний операнд, мы можем применять к ?: те же правила приоритетов и ассоциативности, что и для = (а также других операторов группы присваивания). Почему Страуструп до этого не додумался — это уже другой вопрос.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.