Автор Тема: C++ инициализация ссылок  (Прочитано 56214 раз)

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #15 : Март 15, 2013, 06:44:31 pm »

Во-первых это не локальная переменная, а возвращаемое значение (то что было в моем примере).
Во-вторых это да, полностью безопасно и полностью легально в языке (этот кейс явно прописан в стандарте).
Не совсем так... значение это есть ЗНАЧЕНИЕ.. ,адрес ПЕРЕМЕННОЙ есть адрес...  я говорю про то, что вы не  можете же
сделать  int  & b=456; ... а тут аналогично присваивается ЧТО? впрочем если этот случай рассматривается отдельно.. почему бы и нет..., только стройности языку это не прибавляет...

int &b = 456 я сделать конечно не могу, а вот
const int& b = 456 сделать я безусловно могу, это абсолютно валидная операция.
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #16 : Март 15, 2013, 06:49:59 pm »

const int& b = 456 сделать я безусловно могу, это абсолютно валидная операция.
и... что она делает?

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #17 : Март 15, 2013, 06:52:57 pm »

const int& b = 456 сделать я безусловно могу, это абсолютно валидная операция.
и... что она делает?
Как обычно, создает алиас. Ссылки больше ничего и не делают в общем то, это тупо алиасы.
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #18 : Март 15, 2013, 07:00:56 pm »

const int& b = 456 сделать я безусловно могу, это абсолютно валидная операция.
и... что она делает?
Как обычно, создает алиас. Ссылки больше ничего и не делают в общем то, это тупо алиасы.
на что?

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #19 : Март 15, 2013, 07:06:37 pm »

const int& b = 456 сделать я безусловно могу, это абсолютно валидная операция.
и... что она делает?
Как обычно, создает алиас. Ссылки больше ничего и не делают в общем то, это тупо алиасы.
на что?
На 456, очевидно. Какими именно механизмами компилятор будет обеспечивать аиасность этого алиаса - дело десятое. В зависимости от ситуации он может использовать то одно, то другое, то комбинацию.

Так что нет, ссылка в плюсах это никак не указатель. У ссылки совершенно другая семантика.
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #20 : Март 15, 2013, 07:12:36 pm »

const int& b = 456 сделать я безусловно могу, это абсолютно валидная операция.
и... что она делает?
Как обычно, создает алиас. Ссылки больше ничего и не делают в общем то, это тупо алиасы.
на что?
На 456, очевидно. Какими именно механизмами компилятор будет обеспечивать аиасность этого алиаса - дело десятое. В зависимости от ситуации он может использовать то одно, то другое, то комбинацию.

Так что нет, ссылка в плюсах это никак не указатель. У ссылки совершенно другая семантика.
а причем здесь семантика...  ну хорошо , а в чем отличие от  const int b=456 - разве здесь  b не является "алиясом" числа 456?

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #21 : Март 15, 2013, 07:33:01 pm »
а причем здесь семантика...  ну хорошо , а в чем отличие от  const int b=456 - разве здесь  b не является "алиясом" числа 456?
А там начинаются тонкие различия. Ну, например const_cast похоже работает над ними по разному.

void foo(int* p) {*p=12;}

int main() {
    const int& a = 42;
    const int  b = 42;
    foo(const_cast<int*>(&a));
    foo(const_cast<int*>(&b));
    cout << a << " " << b  << endl;
    return 0;
}

На gcc имеем два разных числа. На clang имеем два одинаковых числа :-D
Одно из двух - либо тут мы имеем UB, либо gcc глючит.

$ g++ --version
g++ (Debian 4.4.5-8) 4.4.5
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #22 : Март 15, 2013, 07:37:16 pm »
Ду, ну и const int b можно влепить volatile и под него будет гарантированно выделена память (и вполне вероятно, оно и так будет выделено), а вот со ссылкой такой фокус не пройдет.
Y = λf.(λx.f (x x)) (λx.f (x x))

Berserker

  • Sr. Member
  • ****
  • Сообщений: 254
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #23 : Март 15, 2013, 07:43:28 pm »
alias - это синоним.

На практике этот синоним поддерживает операцию получения адреса объекта, а значит хранит где-то этот адрес, за исключением оптимизаций. Так вот ячейка памяти, хранящая чей-то адрес, как была указателем, так и остаётся.

Что касаемо оптимизаций, то они просты. Если ссылка на деле указывает на объект в стеке/глобальный объект или как в примере с 456 ни на что не указывает, то нет нужды хранить указатель в памяти и выполнять операцию разыменования. Однако я уже привёл пример с goto, когда реальное значение ссылки меняется. Следовательно, компилятор либо всегда безопасно реализует ссылки через указатели, либо анализирует поток управления.

Ещё раз повторю. Ссылка не синоним. Ведь синоним можно было бы заменить оригинальным объектом во всех местах упоминания. Скажем, если ref является синонимом s[0], то упоминание ref можно было бы заменить на s[0], но это не так по двум причинам:

1) s[0] может скрыто вести к вызову метода, а значит это выражение динамическое. Единственный остающийся вариант всегда указывать на то, что когда-то было s[0] — это хранить указатель или адрес памяти.

2) Пример с goto показывает, что поменять адрес у ссылки можно. После этого она и логически (s[1], s[2]) и физически (&s[1], &s[2]) указывает на новый объект.

Тут у меня вопросов к Defective C++ FQA Lite нет.

P.S. Я ничего не критикую, просто мистика и чёрная магия в описаниях к реальной практике отношения имеют мало.

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #24 : Март 15, 2013, 07:45:07 pm »
alias - это синоним.


нет  alias - это ПСЕВДОНИМ (т.е. ДРУГОЕ НАЗВАНИЕ ОДНОГО И ТОГО ЖЕ ОБЬЕКТА -так переводится)

Berserker

  • Sr. Member
  • ****
  • Сообщений: 254
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #25 : Март 15, 2013, 07:50:56 pm »
Да, я оговорился.

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #26 : Март 15, 2013, 08:07:44 pm »
Если ссылка на деле указывает на объект в стеке/глобальный объект или как в примере с 456 ни на что не указывает, то нет нужды хранить указатель в памяти и выполнять операцию разыменования.
  пример,  с 456  можно трактовать  - как сохранение адреса области памяти  в которой хранится значение 456 - и если оптимизация отключена - то эта константа ДОЛЖНА быть сохранена  в  какой то  ячейке памяти.. кстати, этот фокус (как напомнил Алексей ),  можно проделать только используя модификатор  const, что в принципе говорит об "особом" варианте интерпретации...

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #27 : Март 16, 2013, 12:56:47 am »
Насколько я помню, модификация константного объекта - это UB. Т.е. const_cast валиден только для объекта, который не константен в оригинале (а, например, передан по константной ссылке).

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #28 : Март 16, 2013, 02:04:46 am »
Насколько я помню, модификация константного объекта - это UB.

Но вот такой код обязан работать везде и с любыми оптимизациями:
void f(int const& n){const_cast<int&>(n) = 456;}
int n = 123;
f(n);
assert(n == 456);

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #29 : Март 18, 2013, 09:50:18 am »

void f(int const& n){const_cast<int&>(n) = 456;}
int n = 123;
f(n);
assert(n == 456);
это понятно и потому и не интересно.. лучше ответьте на следующий вопрос -в чем прелесть
const int t& b = rvalue; в сравнении с const int t b = rvalue;? (именно для этого специального случая  - когда rvalue ЗНАЧЕНИЕ соответствующего типа ;)  этот вопрос в том числе и  к Алексею , коль скоро  он такую хренотень привел... то есть перефразирую вопрос.. А на хрена нам нужно эмулировать первое выражение с помощью указателей?  )