Здравствуйте, achp, Вы писали:
A>Здравствуйте, Nortsx, Вы писали:
N>>Что означает зщапись например int& i = какому нить другмоу инту. N>>Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя. N>>Вот правда не понимаю
A>Почему нужно спрашивать на форуме то, что прописано в любом учебнике?
Если найдете цитату из страуструпа или откуда то еще где написано
int& i отличается от &имя переменной тем то и тем то, то... ну вы понимаете
Здравствуйте, abrarov, Вы писали:
A>Здравствуйте, Nortsx, Вы писали:
N>>>>
N>>>> char a = 'a';
N>>>> char b = 'b';
N>>>> char c;
N>>>> char d;
N>>>> char e;
N>>>> char* ptr = &a;
N>>>> c = *ptr++;
N>>>> d = *ptr--;
N>>>> e = *ptr;
N>>>>
A>>>И что? Что-то поменялось? N>>e = неясно чему. Вот в чем проблема. N>>Проверял виндовым компилятором.
A>Может хватит "высасывать из пальца" проблему? A>e == 'a' это A>1) по всем правилам C++ A>2) проверено Visual C++ 10.0
Проверил сегондя еще раз — теперь все оп правилам с++. ящитаю я наконец то освоился и тему можно закрывать. Спасибо за желание помочь нубу)
Здравствуйте, abrarov, Вы писали:
A>Может хватит "высасывать из пальца" проблему? A>e == 'a' это A>1) по всем правилам C++ A>2) проверено Visual C++ 10.0
По всем правилам С++ эта программа может делать всё, что угодно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, abrarov, Вы писали:
A>Можно подробнее? Или у меня просто с юмором туго? Словосочетание "правила C++", кончено, режет слух.
char a = 'a';
char b = 'b';
char c;
char d;
char e;
char* ptr = &a;
c = *ptr++;
d = *ptr--;
e = *ptr;
Выделенная строчка содержит разыменование недействительного указателя, что приводит к неопределённому поведению. Стандарт языка не предъявляет никаких требований к поведению программы, содержащей неопределённое поведение.
На практике эта строчка может «снести крышу» оптимизирующему компилятору.
Здравствуйте, abrarov, Вы писали:
A>Можно подробнее? Или у меня просто с юмором туго? Словосочетание "правила C++", кончено, режет слух.
Там вроде как разименование невалидного указателя. Это UB дальше может быть что угодно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, abrarov, Вы писали: A>>Можно подробнее? Или у меня просто с юмором туго? Словосочетание "правила C++", кончено, режет слух. E>Там вроде как разименование невалидного указателя. Это UB дальше может быть что угодно...
Что-то не пойму, почему указатель перестал быть валидным? От того, что его сначала инкрементировали, а затем декрементировали, что-то изменилось? Становится интересно. Можно привести ссылку на соотв. пункт в стандарте?
Уже взятие адреса переменной a и дальнейшая работа с указателем ptr, я полагаю, должна заставить оптимизирующий компилятор расположить переменную a в стеке (а не пытаться "схитрить" с регистрами).
Или тут что-то с "коварным" aliasing/strict aliasing?
Programs must be written for people to read, and only incidentally for machines to execute
> С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, > так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; > &a не указывает на элемент массива.
Так? Что-то не найду этого в стандарте.
Programs must be written for people to read, and only incidentally for machines to execute
For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.
C++03 — 5.7 Additive operators — p.4:
For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.
Значит, я все таки прав и e == 'a' ?
Programs must be written for people to read, and only incidentally for machines to execute
A>char a = 'a';
A>char b = 'b';
A>char c;
A>char d;
A>char e;
A>char* ptr = &a;
A>c = *ptr++;
A>d = *ptr--;
A>e = *ptr;
A>
A>Выделенная строчка содержит разыменование недействительного указателя, что приводит к неопределённому поведению. Стандарт языка не предъявляет никаких требований к поведению программы, содержащей неопределённое поведение. A>На практике эта строчка может «снести крышу» оптимизирующему компилятору.
На рабочем мониторе (только что) едва заметил выделенную строку. Да, в d будет "мусор" (UB). Но программа (в общем случае — указатель не выходит за пределы readable памяти) не должна упасть и компилятору "наплевать" на такие выкрутасы. Я же писал про значение переменной e.
Programs must be written for people to read, and only incidentally for machines to execute
Здравствуйте, achp, Вы писали:
A>Здравствуйте, abrarov, Вы писали:
A>>Можно подробнее? Или у меня просто с юмором туго? Словосочетание "правила C++", кончено, режет слух.
A>
A>char a = 'a';
A>char b = 'b';
A>char c;
A>char d;
A>char e;
A>char* ptr = &a;
A>c = *ptr++;
A>d = *ptr--;
A>e = *ptr;
A>
A>Выделенная строчка содержит разыменование недействительного указателя, что приводит к неопределённому поведению. Стандарт языка не предъявляет никаких требований к поведению программы, содержащей неопределённое поведение.
A>На практике эта строчка может «снести крышу» оптимизирующему компилятору.
О, наконец-то дошло. Спасибо и achp, и Erop. Дальше UB будет только UB
Programs must be written for people to read, and only incidentally for machines to execute
Здравствуйте, abrarov, Вы писали:
A>Что-то не пойму, почему указатель перестал быть валидным? От того, что его сначала инкрементировали, а затем декрементировали, что-то изменилось? Становится интересно. Можно привести ссылку на соотв. пункт в стандарте?
Взяли указатель на скаляр
Сделали ему *, потом ++
Пока что всё хорошо.
Но потом ему сделали * и --, то есть разыменовали указатель в никуда...
A>Уже взятие адреса переменной a и дальнейшая работа с указателем ptr, я полагаю, должна заставить оптимизирующий компилятор расположить переменную a в стеке (а не пытаться "схитрить" с регистрами).
Не должна. Компилятор может положить на какое-то время переменную в стек, а потом опять поднять в регистр...
A>Или тут что-то с "коварным" aliasing/strict aliasing?
И с ним тоже.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, achp, Вы писали:
A>Здравствуйте, abrarov, Вы писали:
A>>Можно подробнее? Или у меня просто с юмором туго? Словосочетание "правила C++", кончено, режет слух.
A>
A>char a = 'a';
A>char b = 'b';
A>char c;
A>char d;
A>char e;
A>char* ptr = &a;
A>c = *ptr++;
A>d = *ptr--;
A>e = *ptr;
A>
A>Выделенная строчка содержит разыменование недействительного указателя, что приводит к неопределённому поведению. Стандарт языка не предъявляет никаких требований к поведению программы, содержащей неопределённое поведение.
A>На практике эта строчка может «снести крышу» оптимизирующему компилятору.
Тут я немного не понял, почему указатель стал недействительным. Указатель — это переменная, которая хранит адрес. Сначала он хранил адрес переменной a, поэтому значение ptr было корректным. После инкремента указателя адрес по-прежнему корректен (значение переменной ptr изменилось на размер типа char в большую сторону). А что лежит по этому адресу, указателю без разницы. Он честно вернет значение ячейки памяти, на которую указывает. Откуда берется UB?
Здравствуйте, Nortsx, Вы писали:
N>Что означает зщапись например int& i = какому нить другмоу инту. N>Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя. N>Вот правда не понимаю
Ссылки полезно использовать в качестве формальных аргументов функций, чтобы избежать копирования этих самых аргументов. Также я иногда использую ссылки в циклах по контейнерам исключительно в эстетических целях, чтобы не использовать итераторы. Например,
for (std::vector<MyFancyObject>::iterator i = _objects.begin(), iend = _objects.end(); i != iend; ++i)
{
MyFancyObject &obj = *i;
DoStuffWithObject(obj);
}
Не знаю, насколько это снижает производительность цикла, не мерял.
А вообще, да, это базовые вещи, которые отлично разъяснены во всех учебниках.
E>Тут я немного не понял, почему указатель стал недействительным. Указатель — это переменная, которая хранит адрес. Сначала он хранил адрес переменной a, поэтому значение ptr было корректным. После инкремента указателя адрес по-прежнему корректен (значение переменной ptr изменилось на размер типа char в большую сторону). А что лежит по этому адресу, указателю без разницы. Он честно вернет значение ячейки памяти, на которую указывает. Откуда берется UB?
Во-первых, этот указатель всё ещё корректен, только ещё раз его инкрементировать нельзя
Во-вторых, тут UB будет при попытке разименования этого указателя.
Ну и, в-третьих, если по-честному смотреть, то использовать в качестве указателя всякий мусор тоже нельзя. Даже присваивать, а не то, что разименовывать. Тут есть всякие флеймы, по поводу навелидных указателей. Поищи.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, abrarov, Вы писали: A>На рабочем мониторе (только что) едва заметил выделенную строку. Да, в d будет "мусор" (UB). Но программа (в общем случае — указатель не выходит за пределы readable памяти) не должна упасть и компилятору "наплевать" на такие выкрутасы. Я же писал про значение переменной e.
Этого никто не гарантирует.
Во-первых, бывают интерпретаторы С++
Во-вторых, на некоторых RISK архитектурах бывают такие диапазоны адресов, которые читаются/пишутся быстрее. Фактически, это просто массивы отображённых на память регистров. И компилятор может разместить переменную а там, ну и когда ты попробуешь взять адрес соседней с а ячейки, сможешь попасть в границу чего угодно, в том числе и readable памяти...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Edain, Вы писали:
E>Здравствуйте, Nortsx, Вы писали:
N>>Что означает зщапись например int& i = какому нить другмоу инту. N>>Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя. N>>Вот правда не понимаю
E>Ссылки полезно использовать в качестве формальных аргументов функций, чтобы избежать копирования этих самых аргументов. Также я иногда использую ссылки в циклах по контейнерам исключительно в эстетических целях, чтобы не использовать итераторы. Например,
E>