ZAM>Тут кто-то сказал что указатели не нужны... Так если б они были ненужны, их бы никто не использовал. Вот то что указатели вредны -- я могу согласиться. А вредны они, потомучто дают прямой доступ к памяти, а это бооольшое поле для обхода множества ограничений языка т.е. наклёпывания страшных, фатальных и трудноуловимых ошибок.
В свое время, именно работа с указателями выделялась как одно из самых мощных, ключевых средств языка C...
Здравствуйте, rg45, Вы писали:
R>Я имел ввиду вот что: R>
CSomeClass foo( void ); //Результат функции - значение (не ссылка).
//...
CSomeClass& t = foo(); //Временный объект, возвращенный функцией будет жить до тех пор, пока жива ссылка
//...
А там const не потерялось? /Za рулит. И даже если компилятор позволяет писать такие гадости, то надеяться на 12.2/5 уже не приходится.
Ссылки — внутриязыковое средство адресного (косвенного, именного) обращения к данным. Примечание — термин "адресное обращение" используется не в значении "адрес памяти".
Ссылки — суть более высокоуровневая абстракция указателей.
Ссылки введены для повышения эффективности, при использовании указателей-ссылок еще на этапе программирования и проектирования. Для этого для ссылок введены дополнительные ограничения.
Указатель является реальным hardware/software отображаемым объектом, переменной, содержащим адрес. Это значит, что под объект типа указатель будет распределена какая-либо память (например регистровая). Указатели имеют linkage.
Ссылка же предоставляется объектом только в случае невозможности абстракции ее как альтернативного "имени" объекта. В этом случае ссылки мэпятся на указатели. Ссылки не имеют linkage.
Здравствуйте, A.R., Вы писали:
ZAM>>Тут кто-то сказал что указатели не нужны... Так если б они были ненужны, их бы никто не использовал. Вот то что указатели вредны -- я могу согласиться. А вредны они, потомучто дают прямой доступ к памяти, а это бооольшое поле для обхода множества ограничений языка т.е. наклёпывания страшных, фатальных и трудноуловимых ошибок.
AR>В свое время, именно работа с указателями выделялась как одно из самых мощных, ключевых средств языка C...
В своё время, атомные электростанции считались самым безопасным способом вырабатывания электроэнергии...
И, кстати, я не сказал что пользоваться указателями нельзя вообще... как впрочем и атомными электростанциями неперестали пользоваться! ;)
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Здравствуйте, ZAMUNDA, Вы писали:
ZAM>2pullover: ZAM>
ZAM> int val = 10;
ZAM> int *p = &val;
ZAM> // Оператор "*" разименования указателя, даёт rvalue, а у rvalue нельзя взять адрес,
ZAM> // т.е. низя сделать объект с адресом таким же как у объекта у которого адреса нет,
ZAM> // так что IMHO факт того, что такой опенратор скомпилился, является BUG'ом
ZAM> // компилятора, а не языка.
ZAM> int &ref = *p;
ZAM>
А как же, например, такая запись: *p = 1; ? Оператор * как раз имеет тип lvalue. Если есть сомнения, смотри (5.3.1/1).
Здравствуйте, A.R., Вы писали:
AR>Указатель является реальным hardware/software отображаемым объектом, переменной, содержащим адрес. Это значит, что под объект типа указатель будет распределена какая-либо память (например регистровая). Указатели имеют linkage.
Указатели могут не иметь связывания:
int main( void )
{
int * test;
}
AR>Ссылка же предоставляется объектом только в случае невозможности абстракции ее как альтернативного "имени" объекта. В этом случае ссылки мэпятся на указатели. Ссылки не имеют linkage.
Ссылки могут имеют связывание (3.5/2-4). В частности, такая программа является корректной:
tu1.cpp
int io( 10 );
int & i( io );
tu2.cpp
#include <iostream>
extern int & i;
int main( void )
{
::std::cout << i;
}
Однако с остальными аргументами я полностью согласен . Хотелось бы только дополнить.
Я думаю, рассмотрение ссылок и указателей с точки зрения их различий с указателями не является до конца корректным и адекватным. Ссылки и указатели — это абсолютно разные сущности языка с различным синтаксисом и семантикой инициализации и использования, так же, как, например, указатели и арефметические типы.
Если АТ действительно не знаком со ссылками, то, возможно, действительно имеет смысл рассматривать их как аналог уже знакомых сущностей (естественно, учитывая, что такая модель на точность не претендует). В таком случае, я бы указал на двойственную природу ссылок.
Ссылка может быть похожа на указатель. Синтаксически, т.к. и ссылка, и указатель являются compound type и семантически, т.к. и ссылка и указатель — средства непрямого обращения к объекту, возможно, неименованному.
Ссылка может быть похожа на имя объекта. Синтаксически, т.к. обращение к ассоциированному объекту осуществляется посредствам только Lvalue-to-rvalue conversion и семантически, т.к. ссылка может быть синонимом существующего имени, а так же не является объектом и может не требовать storage.
Хорошо, если такая модель поможет понять суть вопроса. Однако для более подробного знакомства необходимо рассматривать ссылку как отдельную сущность, безотносительно к указателю и имени переменной. Тут, скорее, поможет чтение FAQ-ов и другой литературы или поиск по форуму, без конкретных вопросов врядли дискуссия будет конструктивной.
In C++, pointers are objects: they have identity, manifested by a
unique address. References are *not* objects, and do not have
identity. References define a name equivalence; semantically, they
are more closely related to the Fortran `equivalence' statement than
they are to pointers.
A simple example:
struct A { int &a1 ; int &a2 ; } a ;
struct B { int *b1 ; int *b2 ; } b ;
What is guaranteed by the standard: first, sizeof( A ) >= 1 (since A
is an object, although it contains no objects), whereas sizeof( B ) >=
2, since B contains two objects, each of which must have a positive
size. Second: &b.b1 != &b.b2, since b1 and b2 are objects, and must
have an identity manifested by a distinct address. There is no such
guarantee concerning a1 and a2.
и еще одна:
Why don't you read the quote from the C++ standard. There is *no*
case where a reference must occupy storage. A simple example:
struct A
{
int& ri ;
int i ;
A() ;
} ;
In this structure, it is perfectly possible that the offset of i == 0.
Compare:
struct B
{
int *const pi ;
int i ;
B() ;
} ;
A a ;
B b ;
// This assert is *not* guaranteed.
assert( (void*)( &a.i ) != (void*)( &a ) ) ;
// This one is.
assert( (void*)( &b.i ) != (void*)( &b ) ) ;
As both Pete Becker and Steve Clamage have pointed out, a pointer *is*
an object, and must occupy storage. From an OO point of view, a
pointer has identity, which in C++ is materialized by a unique
address. A reference has no such identity, but simply introduce a
name alias, and so requires no such unique address.
Так получилось, что моя работа связана с производством требовательным к уровням надежности и устойчивости. Поэтому я *вынужден* работать только со стандартами. Если в стандарте С++ написано (а там написано ) "a reference can be thought of as a name of an object", я буду верить именно стандарту, но ни кому-нибудь еше. И никакими философскими рассуждениями вы меня не переубедите. Извиняйте.
Здравствуйте, memorilik, Вы писали:
LM>>Это бред. Я приводил примеры, когда замените ссылку нужной переменной невозможно.
M>К сожелению (а может и к счастью) это не бред, а полная правда.
Ранее было также:
M>Т.е. я хотел сказать, что ссылка не является типом данных и под нее память не выделяется !
Здравствуйте, igna, Вы писали:
I>В невыделение памяти вы еще верите?
Хочу сделать одно замечание: данные топик называется "В чем разница ссылки от указателя", так вот, указатель — тип данных, а ссылка — второе имя объекта (переменной). Ссылка не является объектом. Это насчет темы вопроса по существу.
Насчет памяти — вопрос второй, но я пока что по нему мнения не изменил. Т.к. класс — это не просто тип данных, то для того чтобы ответить на этот вопрос надо знать реализацию таблиц переменных класса, таблиц семантических разборов компилятора и т.д и т.п.. К сожелению компиляторами я занимался давольно давно и не очень глубоко, поэтому точно не помню где и что лежит. Если кто-то меня поправит, покажет что память под ссылки выделяется — буду только признателен. Только сразу говорю — sizeof(...) — это не аргумент.
Здравствуйте, memorilik, Вы писали:
M>Здравствуйте, igna, Вы писали:
I>>В невыделение памяти вы еще верите?
M>Хочу сделать одно замечание: данные топик называется "В чем разница ссылки от указателя", так вот, указатель — тип данных, а ссылка — второе имя объекта (переменной). Ссылка не является объектом. Это насчет темы вопроса по существу.
Ну вы люди и даете... угля мелкого, но много !
А как можно к чему-то обратиться не зная его адреса ???????????????????????? Подскажите, плиз !!!
Объясняю. На этапе компиляции компилятор проводит семантический разбор программы. Создает, например, таблицу переменных в которой находиться соответствие переменной и каких-то свойств, строит деревья разбора и т.д. Так вот. Для ссылки переменная ни где не заводиться ! Вместо ссылки подставляется адрес переменной ! И, в вашем случае, именно он (а не какая-то ссылка или ее адрес) кладется в стек ! Тут-то все понятно ?
Говорю сразу что это схема — сильно(очень сильно) упрощенная ! Для классов и вовсе все сложнее !
ЗЫ. Я думаю если вы сможете обратиться к "чему-то" в "компьютере" не указав адрес это "чего-то" — нобелевская премия вам гарантирована !
Здравствуйте, memorilik, Вы писали:
M>Объясняю. На этапе компиляции компилятор проводит семантический разбор программы. Создает, например, таблицу переменных в которой находиться соответствие переменной и каких-то свойств, строит деревья разбора и т.д. Так вот. Для ссылки переменная ни где не заводиться ! Вместо ссылки подставляется адрес переменной ! И, в вашем случае, именно он (а не какая-то ссылка или ее адрес) кладется в стек ! Тут-то все понятно ?
Это... Кхм... Вы же не про заводится — не заводится писали, а про то, что память не выделяется:
M>Т.е. я хотел сказать, что ссылка не является типом данных и под нее память не выделяется !
Я же утверждаю, что при передаче параметра по ссылке в общем случае память под ссылку выделяется (в стеке).
Здравствуйте, igna, Вы писали:
I>Это... Кхм... Вы же не про заводится — не заводится писали, а про то, что память не выделяется: I>Я же утверждаю, что при передаче параметра по ссылке в общем случае память под ссылку выделяется (в стеке).
А если ложки не существует, то как она может оказаться в стеке ?
В стек кладется адрес объекта на который ссылка ссылается. Но не ссылка.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>В стек в языке С++ ничего не кладется. Потому что в С++ нет никакого аппаратного стека.
А в языке ассемблер какой стек ? Аппаратный ? Или, перефразирую одну шутку, — "язык С++ намного эффективнее ассемблера потому, что выполняет многие команды минуя процессор" ? Стек, он и в Африке — стек. И аппаратный он бывает тока на специализированном железе.
PD>А в рабочей программе туда кладется в обоих случаях адрес переменной. А адрес — такого понятия в С++ тоже нет.
Куда — туда ? В стек ? И адрес — такое понятие в С++ есть. Адрес — это _значение_ указателя. Можете его даже распечатать, например .
PD>А есть ссылки и указатели.
Здравствуйте, memorilik, Вы писали:
M>А если ложки не существует, то как она может оказаться в стеке ? M>В стек кладется адрес объекта на который ссылка ссылается. Но не ссылка.
Знаете что. Так конечно можно договориться и до того, что ссылка вообще никогда не требует памяти, в том числе, если она является членом. Не ссылка это мол, а адрес объекта и все тут. Можно. Но не нужно. Напоминаю, вы писали:
M>Т.е. я хотел сказать, что ссылка не является типом данных и под нее память не выделяется !
А стандарт допускает выделение памяти под ссылку:
It is unspecified whether or not a reference requires storage. (8.3.2/3)
И вот еще из Страуструпа:
In some cases, the compiler can optimize away a reference so that there is no object representing that reference at runtime. (5.5 References)
Как видите "unspecified" и "in some cases", так что в общем случае нельзя утверждать, что память под ссылку не выделяется.
Здравствуйте, memorilik, Вы писали:
M>ЗЫ. Я думаю если вы сможете обратиться к "чему-то" в "компьютере" не указав адрес это "чего-то" — нобелевская премия вам гарантирована !
Тривиально. Я, как автор гипотетического интерпретатора C++, могу сделать, чтобы ссылки представлялись текстовыми строками вида «член second переменной foo, объявленной во втором цикле for функции bar, вызванной из функции quux, вызванной из функции main». И в рантайме хранить значения переменных как std::map<std::string, boost::any>. Конечно, в конце концов неявно всё равно всё сведётся к адресам, но в представлении ссылок адресов не будет.
"memorilik" <54054@users.rsdn.ru> wrote in message news:1885476@news.rsdn.ru... > > Т.е. я хотел сказать, что ссылка не является типом данных и под нее память не выделяется !
То, что это не так, можно продемонстрировать следующем фрагментом, который Комо компилирует без ошибок:
struct Pointers{
int *m1,*m2,*m3,*m4;
};
struct References{
int &m1,&m2,&m3,&m4;
References();
};
int test[sizeof(References) == sizeof(Pointers)];
Posted via RSDN NNTP Server 2.0
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, memorilik, Вы писали:
M>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>В стек в языке С++ ничего не кладется. Потому что в С++ нет никакого аппаратного стека. M>А в языке ассемблер какой стек ? Аппаратный ? Или, перефразирую одну шутку, — "язык С++ намного эффективнее ассемблера потому, что выполняет многие команды минуя процессор" ? Стек, он и в Африке — стек. И аппаратный он бывает тока на специализированном железе.
Вынужден тебя разочаровать. В процессоре x86 есть именно аппаратный стек. И регистр ESP именно на него показывает.
PD>>А в рабочей программе туда кладется в обоих случаях адрес переменной. А адрес — такого понятия в С++ тоже нет. M>Куда — туда ? В стек ? И адрес — такое понятие в С++ есть. Адрес — это _значение_ указателя.
Можете его даже распечатать, например .
Распечатать можно именно сам указатель. В формате %d или %x или %p. Равно как можно распечатать переменную типа int.
А вот то , что значением указателя является именно адрес — ссылку на стандарт, пожалуйста. Потому что это , вообще говоря, неверно. Адрес — понятие машинно-зависимое. И вообще, что такое адрес ? К примеру, для x86 — какой именно адрес ? Надеюсь, тебе известно, что численным значением указателя является виртуальный адрес в смысле страничного механизма x86. А еще есть физический адрес, его тебе не видать в программе 3 кольца на С++ как своих ушей . Такие понятия в машинно-независимый язык закладываться не могут.