Почему ссылки на одну и ту же константу занимают различное пространство памяти в C ++? - PullRequest
0 голосов
/ 22 ноября 2018

Я новичок в идее ссылки в C ++, у меня есть вопрос, касающийся выделения памяти ссылки на чистую числовую константу.(Еще одна вещь, которую я хочу проверить в первую очередь, это то, что я подозреваю, что const reference , с которым я часто сталкивался, означает ссылка на const , но я не уверен.)

Вот мое тестирование на ideone.com :

#include <stdio.h>

int main() {

    const int r0 = 123;
    const int &r1 = 123;
    const int &r2 = 123;
    const int &r3 = r2;

    printf("%p\n", (void *)&r0);
    printf("%p\n", (void *)&r1);
    printf("%p\n", (void *)&r2);
    printf("%p\n", (void *)&r3);

    return 0;
}

и результат:

0x7ffee3bd74c4
0x7ffee3bd74c8
0x7ffee3bd74cc
0x7ffee3bd74cc

Причина r2 такая же, как r3 ясно из этого ответа - Как выглядит ссылка C ++ с точки зрения памяти? , которая говорит, что это зависит от компилятора.Но я думаю о том, почему компилятор также не делает r0, r1, r2 одинаковыми, поскольку все имеют одно и то же чистое постоянное значение 123.(или называется prvalue, если нет неправильного поиска)

Как примечание: После некоторых поисков на этом сайте я нашел наиболее связанный вопрос - но в python .Хотя это и другой язык, но я подумал, что идея должна быть одинаковой / похожей: по ссылке, если моя программа была написана на python, в памяти будет только один 123 для экономии места.

Некоторые другие ответы, которые я прочитал:

  1. C ++ ссылки занимают память : Этот ответ предполагает, что если это необходимо, то int &x реализуется как *(pointer_to_x).
  2. Как выглядит ссылка C ++ с точки зрения памяти? : Этот ответ предполагает, что компилятор постарается сделать все возможное, чтобы сэкономить место.

Ответы [ 3 ]

0 голосов
/ 22 ноября 2018

Литерал не является объектом.Ссылки не относятся к буквальному.Когда вы инициализируете ссылку, используя литерал, будет создан временный объект, и время жизни временного объекта будет привязано к времени жизни ссылки.

Объекты (одна локальная переменная, два временных) являются отдельнымии отдельные объекты, несмотря на то, что имеют одинаковое значение.Поскольку они разделены, они занимают отдельные области памяти.Стандарт предписывает это, и это позволяет идентифицировать и различать объекты на основе их адреса памяти.

0 голосов
/ 22 ноября 2018

Три оператора объявления:

const int &r1 = 123;
const int &r2 = 123;
const int &r3 = r2;

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

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

Поскольку ссылки связаны с 3 различными временными, вы не можетенаблюдайте за этими объектами по перекрывающимся адресам.

Интересно, что правило «как если» может, вероятно, позволить программе размещать все три временных объекта по одному и тому же адресу, но только если ваш компилятор и компоновщик теоретически могут доказать, что ваша программа никогда не сможетнаблюдать за этими объектами, расположенными по одному адресу.В вашем примере это невозможно, поскольку вы печатаете адрес объектов.

0 голосов
/ 22 ноября 2018

Ваш 123 не является "константой".Скорее, это литерал .Литерал формирует выражение, которое является prvalue (то есть временным объектом, инициализированным значением, заданным литералом).Когда вы связываете это выражение со ссылкой, время жизни этого объекта увеличивается до срока действия ссылки, но важным моментом здесь является то, что каждый такой объект является отдельным объектом и, следовательно, имеет отдельный адрес.

Если хотите, текстовая строка «123» предоставляет правило о том, как создавать объекты, но сама по себе она не является объектом.Вы можете переписать свой код, чтобы сделать это более явным:

const int & r = int(123);   // temporary of type "int" and value "123"

(В C ++ нет такого понятия, как «константа». Есть много вещей, которые так или иначе постоянны, но онивсе нужно более детально рассмотреть.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...