Что должно выполняться по стандарту Си?
От: lis_asm  
Дата: 23.11.19 21:29
Оценка:
Доброе время суток! Надеюсь, хоть и сомневаюсь, что тут найдутся знатоки стандарта Си(++). Суть вопроса в следующем. Пусть pointer — указатель, скажем, на char. рассмотрим такую конструкцию:
if (pointer && *pointer)
{
...
}

Т.е. мы проверяем корректность указателя на строку, проверяем не пустая ли она, и потом что-то делаем. По стандарту определены порядок выполнения операция слева направо, а так же приоритет. Данная конструкция скомпилится в нечто подобное:

cmp pointer,0
jz m1
mov rax,pointer
cmp byte ptr [rax],0
jz m1
........
m1:

И так на всех компиляторах и платформах, которые мне встречались. Однако, прописано ли явно в стандарте, что второй аргумент && не должен вычисляться? Т.е. если попытка чтения по указателю таки будет выполнена, а потом выполнится &&, это будет противоречить стандартам?

Приведу еще аналогичный случай.

int a = 10;
int b = 20;
int c = 0 ? ++a : ++b;

После выполнения виденными мной компиляторами a == 10, b == 21, c == 21. Однако обязан ли компилятор не выполнять выражение ++a ? Т.е. если результат a == 11, b == 21, c == 21, это правильно с точки зрения стандарта языка?
Отредактировано 23.11.2019 21:55 lis_asm . Предыдущая версия . Еще …
Отредактировано 23.11.2019 21:42 lis_asm . Предыдущая версия .
Отредактировано 23.11.2019 21:39 lis_asm . Предыдущая версия .
си стандарт приоритет
Re: Что должно выполняться по стандарту Си?
От: niXman Ниоткуда https://github.com/niXman
Дата: 23.11.19 22:10
Оценка:
Здравствуйте, lis_asm, Вы писали:

_>Т.е. если попытка чтения по указателю таки будет выполнена, а потом выполнится &&, это будет противоречить стандартам?


вы уже ответили на этот вопрос выше: слева — направо.

во втором случае так же, выражение ++a вычисляться не будет.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 23.11.2019 22:10 niXman . Предыдущая версия .
Re: Что должно выполняться по стандарту Си?
От: Vamp Россия  
Дата: 23.11.19 22:33
Оценка: +6
Здравствуйте, lis_asm, Вы писали:

_>Доброе время суток! Надеюсь, хоть и сомневаюсь, что тут найдутся знатоки стандарта Си(++).


Странный посыл. Это — один из сильнейших форумов по С++ на русском языке, знатоки стандарта здесь безусловно найдутся.

_>И так на всех компиляторах и платформах, которые мне встречались. Однако, прописано ли явно в стандарте, что второй аргумент && не должен вычисляться? Т.е. если попытка чтения по указателю таки будет выполнена, а потом выполнится &&, это будет противоречить стандартам?


Прописано. [expr.log.and], 7.6.14 в текущем драфте:

[quote]
Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
[/quote]

_>Приведу еще аналогичный случай.


_>int a = 10;

_>int b = 20;
_>int c = 0 ? ++a : ++b;

_>Однако обязан ли компилятор не выполнять выражение ++a ?


Да, обязан. В данном случае работает другой пункт стандарта, [expr.cond], 7.6.16

[quote]
It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression. Only one of the second and third expressions is evaluated.
[/quote]
Да здравствует мыло душистое и веревка пушистая.
Re: Что должно выполняться по стандарту Си?
От: Pzz Россия https://github.com/alexpevzner
Дата: 23.11.19 23:52
Оценка: 1 (1) +2
Здравствуйте, lis_asm, Вы писали:

_>И так на всех компиляторах и платформах, которые мне встречались. Однако, прописано ли явно в стандарте, что второй аргумент && не должен вычисляться? Т.е. если попытка чтения по указателю таки будет выполнена, а потом выполнится &&, это будет противоречить стандартам?


В случае Си, да, операнды логических операций выполняются слева на права.

В случае C++ все несколько сложнее. Встроенные логические операции выполняются, как в Си, а вот перегруженные — как компилятору приспичит.
Re[2]: Что должно выполняться по стандарту Си?
От: niXman Ниоткуда https://github.com/niXman
Дата: 24.11.19 00:32
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>... перегруженные — как компилятору приспичит.


уверен?
не путаешь с вычислением аргументов функций?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: Что должно выполняться по стандарту Си?
От: Masterspline  
Дата: 24.11.19 02:44
Оценка: +4
Pzz>В случае C++ все несколько сложнее. Встроенные логические операции выполняются, как в Си, а вот перегруженные — как компилятору приспичит.

При перегрузке &&, ||, по-моему, только отменяется short circuit evaluation, когда значение выражения становится известным при вычислении первого аргумента и второй не вычисляется. Потому что после перегрузки это становится уже не логическое выражение, а какое автор захотел, в результате всегда считаются оба выражения. Однако, ассоциативность слева направо остается.
Re[2]: Что должно выполняться по стандарту Си?
От: lis_asm  
Дата: 24.11.19 05:21
Оценка:
Отредактировано 24.11.2019 5:23 lis_asm . Предыдущая версия .
Re[2]: Что должно выполняться по стандарту Си?
От: lis_asm  
Дата: 24.11.19 05:26
Оценка:
V>Прописано. [expr.log.and], 7.6.14 в текущем драфте:

V>[quote]

V>Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
V>[/quote]


V>Да, обязан. В данном случае работает другой пункт стандарта, [expr.cond], 7.6.16


V>[quote]

V>It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression. Only one of the second and third expressions is evaluated.
V>[/quote]

Спасибо! Собственно это и интересовало. Только в случае интерпретатора это существенно все усложняет, к сожалению..
Re[3]: Что должно выполняться по стандарту Си?
От: Pzz Россия https://github.com/alexpevzner
Дата: 24.11.19 08:34
Оценка: +1
Здравствуйте, Masterspline, Вы писали:

M>При перегрузке &&, ||, по-моему, только отменяется short circuit evaluation, когда значение выражения становится известным при вычислении первого аргумента и второй не вычисляется. Потому что после перегрузки это становится уже не логическое выражение, а какое автор захотел, в результате всегда считаются оба выражения. Однако, ассоциативность слева направо остается.


Я не про ассоциативность, а про порядок вычислений.

С оператором "запятая", кстати, та же самая история.
Re[3]: Что должно выполняться по стандарту Си?
От: Pzz Россия https://github.com/alexpevzner
Дата: 24.11.19 08:34
Оценка:
Здравствуйте, niXman, Вы писали:

Pzz>>... перегруженные — как компилятору приспичит.


X>уверен?


Уверен.

X>не путаешь с вычислением аргументов функций?


Не путаю.
Re[2]: Что должно выполняться по стандарту Си?
От: lis_asm  
Дата: 24.11.19 09:20
Оценка:
V>Прописано. [expr.log.and], 7.6.14 в текущем драфте:

V>[quote]

V>Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
V>[/quote]

С && все понятно, но с &... Например, так:
int a = 10;
int b = false & a++;
Ну или
int a = 10;
int b = 0 & a++;
На VS2012, VS2017 инкремент таки происходит... Выходит, или компилятор неправильно работает, или на этот счет разные стандарты..
Re[3]: Что должно выполняться по стандарту Си?
От: Pzz Россия https://github.com/alexpevzner
Дата: 24.11.19 09:44
Оценка:
Здравствуйте, lis_asm, Вы писали:

_>С && все понятно, но с &... Например, так:


& не является логической операцией. С ней нет никаких гарантий относительно порядка вычислений.
Re[3]: Что должно выполняться по стандарту Си?
От: lis_asm  
Дата: 24.11.19 09:47
Оценка: +1
Здравствуйте, lis_asm, Вы писали:

V>>Прописано. [expr.log.and], 7.6.14 в текущем драфте:


V>>[quote]

V>>Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
V>>[/quote]

_>С && все понятно, но с &... Например, так:

_> int a = 10;
_> int b = false & a++;
_>Ну или
_> int a = 10;
_> int b = 0 & a++;
_>На VS2012, VS2017 инкремент таки происходит... Выходит, или компилятор неправильно работает, или на этот счет разные стандарты..

А, торможу, в отличии от &
Re: Что должно выполняться по стандарту Си?
От: Molchalnik  
Дата: 25.11.19 20:56
Оценка:
Здравствуйте, lis_asm, Вы писали:

_>Доброе время суток! Надеюсь, хоть и сомневаюсь, что тут найдутся знатоки стандарта Си(++).

Да воздастся каждому по желаниям его.

_> Суть вопроса в следующем. Пусть pointer — указатель, скажем, на char. рассмотрим такую конструкцию:

_>if (pointer && *pointer)

Стандарт гарантирует, что если оператор && не перегружен, то второй оператор не выполнится при (bool)pointer == false

на самом деле здесь семь операций:

1) cast к (bool) переменной pointer'а
2) сравнение (bool)pointer с true
3) ЕСЛИ pointer не нуль, И operator&& НЕ перегружен, ТОГДА (выполнить следующие 4 пункта)
4) разыменовать указатель
5) привести *pointer к bool
6) сравнить (bool)*pointer с true
7) выполнить && (будет выкинуто компилятором, если operator&& не перегружен)
Отредактировано 25.11.2019 21:08 Molchalnik . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.