Сообщение Что должно выполняться по стандарту Си? от 23.11.2019 21:29
Изменено 23.11.2019 21:39 lis_asm
Что должно выполняться по стандарту Си?
Доброе время суток! Надеюсь, хоть и сомневаюсь, что тут найдутся знатоки стандарта Си(++). Суть вопроса в следующем. Пусть pointer — указатель, скажем, на char. рассмотрим такую конструкцию:
if (pointer && *pointer)
{
...
}
Т.е. мы проверяем корректность указателя на строку, проверяем не пустая ли она, и потом что-то делаем. По стандарту определены порядок выполнения операция слева направо, а так же приоритет. Данная конструкция скомпилится в нечто подобное:
cmp ptr,0
jz m1
mov rax,ptr
cmp byte ptr [rax],0
jz m1
........
m1:
И так на всех компиляторах и платформах, которые мне встречались. Однако, прописано ли явно в стандарте, что второй аргумент && не должен вычисляться? Т.е. если скомпилить примерно так:
mov rax,pointer
xor rdx,rdx
mov dl,[rax]
or rdx,rax
jz m1
.........
m1:
Т.е. мы вычисляем оба аргумента &&, потом делаем бранч. Это будет противоречить стандартам?
Приведу еще аналогичный случай.
int a = 10;
int b = 20;
int c = 0 ? a++ : b++;
После выполнения виденными мной компиляторами a == 10, b == 21, c == 20. Однако обязан ли компилятор не выполнять выражение a++ ? Т.е. если результат a == 11, b == 21, c == 20, это правильно с точки зрения стандарта языка?
if (pointer && *pointer)
{
...
}
Т.е. мы проверяем корректность указателя на строку, проверяем не пустая ли она, и потом что-то делаем. По стандарту определены порядок выполнения операция слева направо, а так же приоритет. Данная конструкция скомпилится в нечто подобное:
cmp ptr,0
jz m1
mov rax,ptr
cmp byte ptr [rax],0
jz m1
........
m1:
И так на всех компиляторах и платформах, которые мне встречались. Однако, прописано ли явно в стандарте, что второй аргумент && не должен вычисляться? Т.е. если скомпилить примерно так:
mov rax,pointer
xor rdx,rdx
mov dl,[rax]
or rdx,rax
jz m1
.........
m1:
Т.е. мы вычисляем оба аргумента &&, потом делаем бранч. Это будет противоречить стандартам?
Приведу еще аналогичный случай.
int a = 10;
int b = 20;
int c = 0 ? a++ : b++;
После выполнения виденными мной компиляторами a == 10, b == 21, c == 20. Однако обязан ли компилятор не выполнять выражение a++ ? Т.е. если результат a == 11, b == 21, c == 20, это правильно с точки зрения стандарта языка?
Что должно выполняться по стандарту Си?
Доброе время суток! Надеюсь, хоть и сомневаюсь, что тут найдутся знатоки стандарта Си(++). Суть вопроса в следующем. Пусть pointer — указатель, скажем, на char. рассмотрим такую конструкцию:
if (pointer && *pointer)
{
...
}
Т.е. мы проверяем корректность указателя на строку, проверяем не пустая ли она, и потом что-то делаем. По стандарту определены порядок выполнения операция слева направо, а так же приоритет. Данная конструкция скомпилится в нечто подобное:
cmp ptr,0
jz m1
mov rax,ptr
cmp byte ptr [rax],0
jz m1
........
m1:
И так на всех компиляторах и платформах, которые мне встречались. Однако, прописано ли явно в стандарте, что второй аргумент && не должен вычисляться? Т.е. если попытка чтения по указателю таки будет выполнена, а потом выполнится &&, это будет противоречить стандартам?
Приведу еще аналогичный случай.
int a = 10;
int b = 20;
int c = 0 ? a++ : b++;
После выполнения виденными мной компиляторами a == 10, b == 21, c == 20. Однако обязан ли компилятор не выполнять выражение a++ ? Т.е. если результат a == 11, b == 21, c == 20, это правильно с точки зрения стандарта языка?
if (pointer && *pointer)
{
...
}
Т.е. мы проверяем корректность указателя на строку, проверяем не пустая ли она, и потом что-то делаем. По стандарту определены порядок выполнения операция слева направо, а так же приоритет. Данная конструкция скомпилится в нечто подобное:
cmp ptr,0
jz m1
mov rax,ptr
cmp byte ptr [rax],0
jz m1
........
m1:
И так на всех компиляторах и платформах, которые мне встречались. Однако, прописано ли явно в стандарте, что второй аргумент && не должен вычисляться? Т.е. если попытка чтения по указателю таки будет выполнена, а потом выполнится &&, это будет противоречить стандартам?
Приведу еще аналогичный случай.
int a = 10;
int b = 20;
int c = 0 ? a++ : b++;
После выполнения виденными мной компиляторами a == 10, b == 21, c == 20. Однако обязан ли компилятор не выполнять выражение a++ ? Т.е. если результат a == 11, b == 21, c == 20, это правильно с точки зрения стандарта языка?