Re[9]: ТУпейший вопрос про указатели
От: Erop Россия  
Дата: 20.07.11 09:39
Оценка: 7 (2) +2
Здравствуйте, abrarov, Вы писали:

A>Может хватит "высасывать из пальца" проблему?

A>e == 'a' это
A>1) по всем правилам C++
A>2) проверено Visual C++ 10.0

По всем правилам С++ эта программа может делать всё, что угодно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: ТУпейший вопрос про указатели
От: Erop Россия  
Дата: 18.07.11 13:38
Оценка: 1 (1) +2
Здравствуйте, Edain, Вы писали:

E>...но это будет _не_ обязательно адрес переменной b, т.к. никто не гарантирует, что a и b будут в памяти расположены последовательно (или гарантирует?).


Для начала, никто не гарантирует, не только размещение переменной b в памяти, а не где-то ещё, в регистрах, например, или ещё где, так и вообще её существования...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: ТУпейший вопрос про указатели
От: abrarov Россия http://asio-samples.blogspot.com/
Дата: 19.07.11 19:49
Оценка: -3
Здравствуйте, 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>Проверял виндовым компилятором.

Может хватит "высасывать из пальца" проблему?
e == 'a' это
1) по всем правилам C++
2) проверено Visual C++ 10.0
Programs must be written for people to read, and only incidentally for machines to execute
Re: ТУпейший вопрос про указатели
От: Edain Верблюд  
Дата: 18.07.11 12:24
Оценка: 1 (1) +1
Здравствуйте, 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>


N>После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?


c будет иметь значение 'a', потому что сначала происходит разыменование, а потом инкремент (т.к. оператор ++ постфиксный). При этом ptr будет указывать на ячейку памяти, расположенную сразу за переменной a (&a + sizeof(char)), но это будет _не_ обязательно адрес переменной b, т.к. никто не гарантирует, что a и b будут в памяти расположены последовательно (или гарантирует?). Поэтому когда выполняется d = *ptr--, переменная d получает в качестве значения мусор, хранящийся по адресу &a + sizeof(char), а указатель вновь будет указывать на a.
Re[3]: ТУпейший вопрос про указатели
От: Masterkent  
Дата: 18.07.11 14:32
Оценка: 6 (1)
achp:

E>>(&a + sizeof(char))


A>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.


Здесь как раз-таки всё законно:

C99 — 6.5.6 Additive operators — p.7:

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.

Re[11]: ТУпейший вопрос про указатели
От: achp  
Дата: 20.07.11 10:39
Оценка: 1 (1)
Здравствуйте, abrarov, Вы писали:

A>Можно подробнее? Или у меня просто с юмором туго? Словосочетание "правила C++", кончено, режет слух.


char a = 'a';
char b = 'b';
char c;
char d;
char e;
char* ptr = &a;
c = *ptr++;
d = *ptr--;
e = *ptr;


Выделенная строчка содержит разыменование недействительного указателя, что приводит к неопределённому поведению. Стандарт языка не предъявляет никаких требований к поведению программы, содержащей неопределённое поведение.

На практике эта строчка может «снести крышу» оптимизирующему компилятору.
Re[11]: ТУпейший вопрос про указатели
От: Erop Россия  
Дата: 20.07.11 10:46
Оценка: 1 (1)
Здравствуйте, abrarov, Вы писали:

A>Можно подробнее? Или у меня просто с юмором туго? Словосочетание "правила C++", кончено, режет слух.


Там вроде как разименование невалидного указателя. Это UB дальше может быть что угодно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: ТУпейший вопрос про указатели
От: abrarov Россия http://asio-samples.blogspot.com/
Дата: 20.07.11 12:36
Оценка: 1 (1)
Здравствуйте, 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
Re[13]: ТУпейший вопрос про указатели
От: Erop Россия  
Дата: 22.07.11 09:40
Оценка: 1 (1)
Здравствуйте, abrarov, Вы писали:
A>На рабочем мониторе (только что) едва заметил выделенную строку. Да, в d будет "мусор" (UB). Но программа (в общем случае — указатель не выходит за пределы readable памяти) не должна упасть и компилятору "наплевать" на такие выкрутасы. Я же писал про значение переменной e.

Этого никто не гарантирует.
Во-первых, бывают интерпретаторы С++
Во-вторых, на некоторых RISK архитектурах бывают такие диапазоны адресов, которые читаются/пишутся быстрее. Фактически, это просто массивы отображённых на память регистров. И компилятор может разместить переменную а там, ну и когда ты попробуешь взять адрес соседней с а ячейки, сможешь попасть в границу чего угодно, в том числе и readable памяти...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: ТУпейший вопрос про указатели
От: boot  
Дата: 18.07.11 11:26
Оценка: +1
Здравствуйте, 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>


N>После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?


А так?
    char a = 'a';
    char b = 'b';
    char c;
    char d;
    char e;
    char* ptr = &a;
    c = *ptr++;
    d = *(--ptr);
Жизнеспособность прямо пропорциональна простоте!
ТУпейший вопрос про указатели
От: Nortsx  
Дата: 18.07.11 11:21
Оценка:
    char a = 'a';
    char b = 'b';
    char c;
    char d;
    char e;
    char* ptr = &a;
    c = *ptr++;
    d = *ptr--;


После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?
Re: ТУпейший вопрос про указатели
От: savitar  
Дата: 18.07.11 11:27
Оценка:
Здравствуйте, Nortsx, Вы писали:

//c = *ptr++;
//d = *ptr--;
// 2 законтированные строчки можно переписать так:
c = *ptr;
++ptr;
d = *ptr;
--ptr;


Вопрос отпадает?
Re[2]: ТУпейший вопрос про указатели
От: Nortsx  
Дата: 18.07.11 11:30
Оценка:
Здравствуйте, savitar, Вы писали:

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


S>
S>//c = *ptr++;
S>//d = *ptr--;
S>// 2 законтированные строчки можно переписать так:
S>c = *ptr;
S>++ptr;
S>d = *ptr;
S>--ptr;
S>


S>Вопрос отпадает?


Это логично, но разве унарные операторы в плюсах не выполняются справа налево?
http://www.cyberguru.ru/programming/cpp/cpp-programming-guide-page35.html здесь вроде так.
Что значит — сначала он должен инкрементировать а потом разыменовать.
Re: ТУпейший вопрос про указатели
От: blackhearted Украина  
Дата: 18.07.11 11:31
Оценка:
Здравствуйте, 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>


N>После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?


пост-декремент?
Re: ТУпейший вопрос про указатели
От: achp  
Дата: 18.07.11 11:41
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>d — указывают на пустую область памяти.


Во-первых, d не может ни на что указывать, т. к. не является указателем.

Во-вторых, непонятно, какой смысл вложен в словосочетание «пустая область памяти».

N>Почему?


Частный случай неопределённого поведения.
Re[2]: ТУпейший вопрос про указатели
От: achp  
Дата: 18.07.11 12:31
Оценка:
Здравствуйте, Edain, Вы писали:

E>(&a + sizeof(char))


С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.

Если какой-нибудь ретивый компилятор наоптимизирует что-то таким образом, что (c != a), то будет в полном праве так поступить.
Re[3]: ТУпейший вопрос про указатели
От: Nortsx  
Дата: 18.07.11 12:36
Оценка:
Здравствуйте, achp, Вы писали:

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


E>>(&a + sizeof(char))


A>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.


A>Если какой-нибудь ретивый компилятор наоптимизирует что-то таким образом, что (c != a), то будет в полном праве так поступить.


Тогда почему после ввода переменной типа char e;
и присвоения e *ptr; (уже после выполнения инкрементирования и декремента)
е тоже будет указывать на мусор в памяти?
Re[4]: ТУпейший вопрос про указатели
От: achp  
Дата: 18.07.11 12:37
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>Тогда почему после ввода переменной типа char e;

N>и присвоения e *ptr; (уже после выполнения инкрементирования и декремента)
N>е тоже будет указывать на мусор в памяти?

Можно уточнить вопрос и конкретизировать его фрагментом кода?
Re: ТУпейший вопрос про указатели
От: abrarov Россия http://asio-samples.blogspot.com/
Дата: 18.07.11 12:41
Оценка:
Здравствуйте, Nortsx, Вы писали:
N>После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?

char a = 'a';
char b = 'b';
char c;
char d;
char e;
char* ptr = &a;
c = *ptr++; // выражение ptr++ - это пост-инкремент. Поэтому *(ptr++) даст 'a'.            
d = *ptr--; // здесь уже ptr указывает на то, что лежало в стеке до того, как в стек была помещена переменная a 
            // (на x86 стек растет в сторону меньших адресов). Т.к. ptr-- тоже пост-инкремент, то
            // d будет указывать как раз таки на то самое, что было "положено" в стек, до появления переменной a.


Вообще пост-инкремент (и пре-инкремент) очень коварный. Рекомендую почитать про точки следования (C++ sequence point). Например, вот здесь.
Programs must be written for people to read, and only incidentally for machines to execute
Re[3]: ТУпейший вопрос про указатели
От: stapter  
Дата: 18.07.11 12:59
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>Это логично, но разве унарные операторы в плюсах не выполняются справа налево?

N>http://www.cyberguru.ru/programming/cpp/cpp-programming-guide-page35.html здесь вроде так.
N>Что значит — сначала он должен инкрементировать а потом разыменовать.
Эта тема должна все прояснить
Автор: Alex Dav
Дата: 20.02.07
Re[5]: ТУпейший вопрос про указатели
От: Nortsx  
Дата: 18.07.11 13:40
Оценка:
Здравствуйте, achp, Вы писали:

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


N>>Тогда почему после ввода переменной типа char e;

N>>и присвоения e *ptr; (уже после выполнения инкрементирования и декремента)
N>>е тоже будет указывать на мусор в памяти?

A>Можно уточнить вопрос и конкретизировать его фрагментом кода?

Конкретизирую)

    char a = 'a';
    char b = 'b';
    char c;
    char d;
    char e;
    char* ptr = &a;
    c = *ptr++;
    d = *ptr--;
    e = *ptr;
Re[4]: ТУпейший вопрос про указатели
От: boot  
Дата: 18.07.11 14:12
Оценка:
Здравствуйте, Nortsx, Вы писали:

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


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


E>>>(&a + sizeof(char))


A>>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.


A>>Если какой-нибудь ретивый компилятор наоптимизирует что-то таким образом, что (c != a), то будет в полном праве так поступить.


N>Тогда почему после ввода переменной типа char e;

N>и присвоения e *ptr; (уже после выполнения инкрементирования и декремента)
N>е тоже будет указывать на мусор в памяти?

Ну не совсем мусор.

#include <stdio.h>

int main(int argc, char* argv[])
{
    char a = 'a';
    char b = 'b';
    int c;
    int d;
    int e;
    char* ptr = &a;
    c = *ptr++;
    d = *ptr--;
    printf("c:%d\nd:%d", c, d);
}

D:\dev\prj\test>hz
c:97
d:-96

#include <stdio.h>

int main(int argc, char* argv[])
{
    char a = 'a';
    char b = 'b';
    int c;
    int d;
    int e;
    char* ptr = &b;
    c = *ptr++;
    d = *ptr--;
    printf("c:%d\nd:%d", c, d);
}

D:\dev\prj\test>hz
c:98
d:97
Жизнеспособность прямо пропорциональна простоте!
Re[2]: И еще один
От: Nortsx  
Дата: 18.07.11 20:05
Оценка:
Что означает зщапись например int& i = какому нить другмоу инту.
Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя.
Вот правда не понимаю
Re[4]: ТУпейший вопрос про указатели
От: achp  
Дата: 19.07.11 12:10
Оценка:
Здравствуйте, Masterkent, Вы писали:

E>>>(&a + sizeof(char))


A>>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.


M>Здесь как раз-таки всё законно:


Хм, действительно. Интересно, зачем такое безобразие сделано…
Re[3]: И еще один
От: achp  
Дата: 19.07.11 12:12
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>Что означает зщапись например int& i = какому нить другмоу инту.

N>Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя.
N>Вот правда не понимаю

Почему нужно спрашивать на форуме то, что прописано в любом учебнике?
Re[6]: ТУпейший вопрос про указатели
От: achp  
Дата: 19.07.11 12:12
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>Конкретизирую)


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>


И что? Что-то поменялось?
Re[4]: И еще один
От: Nortsx  
Дата: 19.07.11 18:19
Оценка:
Здравствуйте, achp, Вы писали:

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


N>>Что означает зщапись например int& i = какому нить другмоу инту.

N>>Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя.
N>>Вот правда не понимаю

A>Почему нужно спрашивать на форуме то, что прописано в любом учебнике?


Если найдете цитату из страуструпа или откуда то еще где написано
int& i отличается от &имя переменной тем то и тем то, то... ну вы понимаете
Re[7]: ТУпейший вопрос про указатели
От: Nortsx  
Дата: 19.07.11 19:20
Оценка:
Здравствуйте, achp, Вы писали:

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


N>>Конкретизирую)


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>И что? Что-то поменялось?

e = неясно чему. Вот в чем проблема.
Проверял виндовым компилятором.
Re[9]: ТУпейший вопрос про указатели
От: Nortsx  
Дата: 19.07.11 20:28
Оценка:
Здравствуйте, 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

Проверил сегондя еще раз — теперь все оп правилам с++. ящитаю я наконец то освоился и тему можно закрывать. Спасибо за желание помочь нубу)
Re[5]: И еще один
От: B0FEE664  
Дата: 20.07.11 10:19
Оценка:
Здравствуйте, Nortsx, Вы писали:

N>int& i отличается от &имя переменной тем то и тем то, то... ну вы понимаете


int a;
int& i = a; // i - ссылка
&a; // операция взятия адреса


ссылка и указатель в С++ — это две разные сущности.
И каждый день — без права на ошибку...
Re[10]: ТУпейший вопрос про указатели
От: abrarov Россия http://asio-samples.blogspot.com/
Дата: 20.07.11 10:31
Оценка:
Здравствуйте, Erop, Вы писали:

E>По всем правилам С++ эта программа может делать всё, что угодно...


Можно подробнее? Или у меня просто с юмором туго? Словосочетание "правила C++", кончено, режет слух.
Programs must be written for people to read, and only incidentally for machines to execute
Re[12]: ТУпейший вопрос про указатели
От: abrarov Россия http://asio-samples.blogspot.com/
Дата: 20.07.11 11:39
Оценка:
Здравствуйте, 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
Re[13]: ТУпейший вопрос про указатели
От: abrarov Россия http://asio-samples.blogspot.com/
Дата: 20.07.11 11:47
Оценка:
> С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение,
> так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива;
> &a не указывает на элемент массива.

Так? Что-то не найду этого в стандарте.
Programs must be written for people to read, and only incidentally for machines to execute
Re[14]: ТУпейший вопрос про указатели
От: abrarov Россия http://asio-samples.blogspot.com/
Дата: 20.07.11 11:59
Оценка:
Вот написано же для achp:


C99 — 6.5.6 Additive operators — p.7:

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
Re[12]: ТУпейший вопрос про указатели
От: abrarov Россия http://asio-samples.blogspot.com/
Дата: 20.07.11 12:32
Оценка:
Здравствуйте, achp, Вы писали:

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>На практике эта строчка может «снести крышу» оптимизирующему компилятору.

На рабочем мониторе (только что) едва заметил выделенную строку. Да, в d будет "мусор" (UB). Но программа (в общем случае — указатель не выходит за пределы readable памяти) не должна упасть и компилятору "наплевать" на такие выкрутасы. Я же писал про значение переменной e.
Programs must be written for people to read, and only incidentally for machines to execute
Re[13]: ТУпейший вопрос про указатели
От: Erop Россия  
Дата: 20.07.11 12:41
Оценка:
Здравствуйте, abrarov, Вы писали:

A>Что-то не пойму, почему указатель перестал быть валидным? От того, что его сначала инкрементировали, а затем декрементировали, что-то изменилось? Становится интересно. Можно привести ссылку на соотв. пункт в стандарте?


Взяли указатель на скаляр
Сделали ему *, потом ++
Пока что всё хорошо.
Но потом ему сделали * и --, то есть разыменовали указатель в никуда...

A>Уже взятие адреса переменной a и дальнейшая работа с указателем ptr, я полагаю, должна заставить оптимизирующий компилятор расположить переменную a в стеке (а не пытаться "схитрить" с регистрами).

Не должна. Компилятор может положить на какое-то время переменную в стек, а потом опять поднять в регистр...

A>Или тут что-то с "коварным" aliasing/strict aliasing?

И с ним тоже.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: ТУпейший вопрос про указатели
От: Edain Верблюд  
Дата: 22.07.11 07:29
Оценка:
Здравствуйте, 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?
Re[3]: И еще один
От: Edain Верблюд  
Дата: 22.07.11 07:39
Оценка:
Здравствуйте, 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);
}


Не знаю, насколько это снижает производительность цикла, не мерял.

А вообще, да, это базовые вещи, которые отлично разъяснены во всех учебниках.
Re[13]: ТУпейший вопрос про указатели
От: Erop Россия  
Дата: 22.07.11 09:36
Оценка:
Здравствуйте, Edain, Вы писали:


E>Тут я немного не понял, почему указатель стал недействительным. Указатель — это переменная, которая хранит адрес. Сначала он хранил адрес переменной a, поэтому значение ptr было корректным. После инкремента указателя адрес по-прежнему корректен (значение переменной ptr изменилось на размер типа char в большую сторону). А что лежит по этому адресу, указателю без разницы. Он честно вернет значение ячейки памяти, на которую указывает. Откуда берется UB?


Во-первых, этот указатель всё ещё корректен, только ещё раз его инкрементировать нельзя
Во-вторых, тут UB будет при попытке разименования этого указателя.
Ну и, в-третьих, если по-честному смотреть, то использовать в качестве указателя всякий мусор тоже нельзя. Даже присваивать, а не то, что разименовывать. Тут есть всякие флеймы, по поводу навелидных указателей. Поищи.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: И еще один
От: Nortsx  
Дата: 25.07.11 09:37
Оценка:
Здравствуйте, Edain, Вы писали:

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


N>>Что означает зщапись например int& i = какому нить другмоу инту.

N>>Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя.
N>>Вот правда не понимаю

E>Ссылки полезно использовать в качестве формальных аргументов функций, чтобы избежать копирования этих самых аргументов. Также я иногда использую ссылки в циклах по контейнерам исключительно в эстетических целях, чтобы не использовать итераторы. Например,


E>
E>for (std::vector<MyFancyObject>::iterator i = _objects.begin(), iend = _objects.end(); i != iend; ++i)
E>{
E>   MyFancyObject &obj = *i;

E>   DoStuffWithObject(obj);
E>}
E>


E>Не знаю, насколько это снижает производительность цикла, не мерял.


E>А вообще, да, это базовые вещи, которые отлично разъяснены во всех учебниках.
Re[5]: И еще один
От: Nortsx  
Дата: 25.07.11 09:38
Оценка:
Здравствуйте, Nortsx, Вы писали:

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


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


N>>>Что означает зщапись например int& i = какому нить другмоу инту.

N>>>Это ссылка, но какую функциональность может она нести, если для взятия ссылки от объекта достаточно &имя.
N>>>Вот правда не понимаю

E>>Ссылки полезно использовать в качестве формальных аргументов функций, чтобы избежать копирования этих самых аргументов. Также я иногда использую ссылки в циклах по контейнерам исключительно в эстетических целях, чтобы не использовать итераторы. Например,


E>>
E>>for (std::vector<MyFancyObject>::iterator i = _objects.begin(), iend = _objects.end(); i != iend; ++i)
E>>{
E>>   MyFancyObject &obj = *i;

E>>   DoStuffWithObject(obj);
E>>}
E>>


E>>Не знаю, насколько это снижает производительность цикла, не мерял.


E>>А вообще, да, это базовые вещи, которые отлично разъяснены во всех учебниках.

Сорри,отправил пустое сообщение.

Как раз такой вопрос у меня и возник после прочтения учебника)
Он звучит не как "зачем нужны ссылки", а как "зачем ссылкам псевдонимы".
Ну я жуе увидел примеры использования, когда улучшается ридабилити кода и т д.
Re: ТУпейший вопрос про указатели
От: wisp Украина  
Дата: 26.01.12 10:17
Оценка:
Здравствуйте, 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>


N>После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?


У меня два варианта:
1) компилятор выделяет каждой переменной два байта,- т.е. выравнивает на границу слова.
2) компилятор оптимизирует код и не выделяет переменным память
Re[2]: ТУпейший вопрос про указатели
От: MasterZiv СССР  
Дата: 26.01.12 11:42
Оценка:
On 01/26/2012 02:17 PM, wisp wrote:

> 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>
>
>
>
> N>После выполнения указаных действий c равно значению а, а d — указывают на
> пустую область памяти. Почему?

d -- char d;, он никуда указывать не может.

> У меня два варианта:

> 1) компилятор выделяет каждой переменной два байта,- т.е. выравнивает на границу
> слова.

Это может быть, но это -- проблемы компилятора.
А твоего кода пролемы, что в этой строке:

d = *ptr--;

ты адресуешся по адресу несуществующей переменной.

> 2) компилятор оптимизирует код и не выделяет переменным память


Тут нет никаких выделений памяти и без оптимизации.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: ТУпейший вопрос про указатели
От: grey_olli http://grey-olli.livejournal.com
Дата: 26.01.12 17:44
Оценка:
Здравствуйте, MasterZiv, Вы писали:

>> N> char a = 'a';

>> N> char b = 'b';
>> N> char d;
>> N> char e;
>> N> char* ptr =&a;
>> N> c = *ptr++;
>> N> d = *ptr--;
>> N>

MZ>d = *ptr--;

MZ>ты адресуешся по адресу несуществующей переменной.

Насколько я понял просмотрев весь тред:
>> N> char* ptr =&a;
>> N> c = *ptr++;
начиная с этого момента в ptr лежит адрес произвольного куска памяти, и если убрать разыменование и просто сделать ptr--, то в дальнейшем какие либо операции по нему будут по прежнему операциями с другим произвольным куском памяти, пусть и отстоящим от него на sizeof(char *).
Уточните новичку — я написал верное резюме по мотивам этого треда? ?-)

PS: Сильно напоминает измерения в ядерной физике в которых постулируют невозможность поиметь сразу и координату и энергию, хотя из того, что вот тут накрутили вокруг квантовых компов: http://www.membrana.ru/particle/1901 вывод можно сделать и такой: эти "квантовые" штуки по сути всего лишь очередной сферический конь в вакууме очень удобный для расчетов, господь бог же не подкидывает монетку желая узнать всё что можно о энергии и координате частицы. =)
--
Bye.Olli.
gpg --search-keys grey_olli
Key fingerprint = 09B6 E060 DD67 04B9 E53B 721B 12E2 7401 F8A4 FC68
Re: ТУпейший вопрос про указатели
От: Кодт Россия  
Дата: 26.01.12 18:58
Оценка:
Здравствуйте, 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>


N>После выполнения указаных действий c равно значению а, а d — указывают на пустую область памяти. Почему?


Потому что компилятор не обязан размещать переменные подряд, сплошь и вверх по стеку.
Только одна переменная — a — обязана иметь адрес и размещаться физически на стеке (т.к. её адрес взяли, ptr=&a).
Другая переменная — d — обязана размещаться где угодно как неконстантная (поскольку ей присваивается нечто произвольное, *(&a+1)).
Переменные b и c можно заменить на константы ('b' и 'a' соответственно) и проинлайнить. Это если компилятор оптимизирующий.

А если не оптимизирующий, и честно размещает переменные на стеке, и не выравнивает их на границу машинного слова (это могло бы повысить скорость доступа), то... ВНЕЗАПНО!
Стек-то у нас растёт вниз.
http://ideone.com/GlgNG
#include <stdio.h>
 
int main()
{
  char a = 'a';
  char b = 'b';
  char c;
  char d;
 
  printf("%p %p %p %p\n", &a, &b, &c, &d);
  printf("%d='%c'\n", (&a)[0], (&a)[0]);
  printf("%d='%c'\n", (&a)[1], (&a)[1]);
}

выводит (сделал 4 попытки)

0xbfdbc217 0xbfdbc216 0xbfdbc215 0xbfdbc214
97='a'
48='0'

0xbfc29d47 0xbfc29d46 0xbfc29d45 0xbfc29d44
97='a'
96='`'

0xbffa35e7 0xbffa35e6 0xbffa35e5 0xbffa35e4
97='a'
0=''

0xbfd20217 0xbfd20216 0xbfd20215 0xbfd20214
97='a'
48='0'

Так что в переменную d в твоём примере попадает не значение b, а кусок служебной информации (адрес возврата, заголовок кадра и т.п.)
Перекуём баги на фичи!
Re[3]: ТУпейший вопрос про указатели
От: Кодт Россия  
Дата: 26.01.12 19:01
Оценка:
Здравствуйте, achp, Вы писали:

E>>(&a + sizeof(char))


A>С точки зрения формальной начиная с этого момента мы имеем неопределённое поведение, так как адресная арифметика дозволяется только над указателями, указывающими на элемент массива; &a не указывает на элемент массива.


Адресная арифметика дозволяется над указателями на массив из одного элемента Другое дело, что мы получаем валидный неразыменовываемый указатель "за конец массива", и вот попытка разыменовать его и является UB.
Перекуём баги на фичи!
Re[12]: ТУпейший вопрос про указатели
От: Кодт Россия  
Дата: 26.01.12 19:03
Оценка:
Здравствуйте, Erop, Вы писали:

E>Там вроде как разименование невалидного указателя. Это UB дальше может быть что угодно...


Валидного. Указатель за конец массива, а также нулевой указатель — вполне себе валидные
Перекуём баги на фичи!
Re[13]: ТУпейший вопрос про указатели
От: Erop Россия  
Дата: 26.01.12 23:02
Оценка:
Здравствуйте, Кодт, Вы писали:

E>>Там вроде как разименование невалидного указателя. Это UB дальше может быть что угодно...


К>Валидного. Указатель за конец массива, а также нулевой указатель — вполне себе валидные


Ну, в смысле, негодного для разыменования...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.