Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Объясните разницу


Автор: wowka19 11.8.2015, 06:25
Вариант 1:
Код

double d = 3.14;
const int i = d;


Вариант 2:
Код

double d = 3.14;
const int &i = d;


Это ведь одно и тоже? как сточки зрения дальнейшей работы с переменными d и i, так с точки зрения конечного машинного кода?
Спасибо.

Автор: Alexeis 11.8.2015, 08:22
Цитата(wowka19 @  11.8.2015,  07:25 Найти цитируемый пост)
так с точки зрения конечного машинного кода?
Спасибо. 

  Не думаю. Во втором варианте создается временная переменная-копия переменной d типа int и i получает на нее ссылку. В 1м случае просто создается константа. Т.е. на одну сущность меньше.

Автор: wowka19 11.8.2015, 08:39
Понятно, что логически это разные вещи, но "сточки зрения дальнейшей работы с переменными d и i, и с точки зрения конечного машинного кода" равнозначно?

Автор: xvr 11.8.2015, 11:25
Теоритически код должен получится другой. Практически оптимизатор в компиляторе (если он достаточно умный) может быть сможет сделать код одинаковым.

По семантике скорее всего разницы не будет.

Автор: Cheloveck 11.8.2015, 11:26
Цитата(wowka19 @  11.8.2015,  09:39 Найти цитируемый пост)
 с точки зрения конечного машинного кода" равнозначно? 

 smile 
user posted image
Хотя, после оптимизации, скорее всего будет равнозначно, но это будет зависить от контекста.

Автор: Alexeis 11.8.2015, 20:32
  Насколько я помню в С++ есть такое правило, что временный объект на который есть константная ссылка продлевает свое время жизни на время пока жива ссылка. Так что результат может зависеть от того какой код будет ниже. В первом случае нет константной ссылки.

Автор: TarasProger 12.8.2015, 06:42
Цитата(wowka19 @  11.8.2015,  08:39 Найти цитируемый пост)
Понятно, что логически это разные вещи, но "сточки зрения дальнейшей работы с переменными d и i, и с точки зрения конечного машинного кода" равнозначно? 
Вам только что объяснили разницу с точки зрения кода.

Добавлено @ 06:48
Цитата(xvr @  11.8.2015,  11:25 Найти цитируемый пост)
По семантике скорее всего разницы не будет.
По семантике разница уже есть: в одном случае просто именнованная константа получает зультат приведения другой переменной к инту в качестве значения, а в другом создаётся безымянная констнатна с таким значением и деклариуется её именованный синоним. Вот смотри: есть психически здововый человек, а есть недошизофреник, заявляющий: "Я не - я, кто то другой, считающий, что он - это я.", семантика их диагнозов различна.

Автор: TarasProger 12.8.2015, 09:03
Что самое интересное, 
Код
 double d = 3.14;
 const double &i = d;// нифига не константа, а просто синоним d: при изменении d, i тоже меняется.
 Но 
Код
 double d = 3.14;
 const double &i = d;
 i=26.44; // Это строка не валидна
.

Добавлено через 2 минуты и 59 секунд
А вот так: 
Код
 double d = 3.14;
 const double i = d;
 i на изменения d не реагирует, это действительно константа.

Автор: wowka19 12.8.2015, 09:11
TarasProger, но в коде при всем желании вы уже не отличите одно от другого. Каким бы не был дальнейший код, принимающий i - результат один и тот же.
Цель моего вопроса-сравнения лучше понять тонкости языка. Интерес вызывает не философия и как это правильно называть (в этом я разобрался), а различия как на уровне дальнейшего использования i, так и внутренняя реализация. Поэтому еще раз: как я в итоге понял что оба варианта с точки зрения дальнейшего использования i - идентичны (если нет, то приведите пример, опровергающий мой вывод), а с точки зрения внутреннего расположения в памяти оба варианта тоже равнозначны - и там и там i - единственное имя участка памяти под int.

Вот еще вопрос:
Вариант 1:
Код

const static int v = 42;

Вариант 2:
Код

const int &v = 42;

В обоих случаях v - имя участка статической памяти под int?
Существует ли код, который ведет себя по-разному в зависимости от варианта определения v?

p.s: TarasProger, ничего странного, ибо const гарантирует только невозможность изменить объект только через идентификатор, к которому этот спецификатор (const) добавлен.

Автор: TarasProger 12.8.2015, 09:33
Цитата(wowka19 @  12.8.2015,  09:11 Найти цитируемый пост)
TarasProger, но в коде при всем желании вы уже не отличите одно от другого. Каким бы не был дальнейший код, принимающий i - результат один и тот же.
Обращающийся код - не весь код, а создание и уничтожение временной переменной - это всё таки операции, которые тоже должны быть закодированы. Пусть в случае 
Код
double d=3.14;
const int &i=d;
 "временная переменная" в силу свой синонимичности d превращается в обычную локальной/глобальной константы. Но в случае 
Код

double d=3.14;
const int i=d;
 имеют место быть две целые величины, а не одна, одна из них действительно временная и после инициализации второй величины уничтожается, вторая же - вполне обычная локальная/глобальная константа. И вот в этом то не уничтожении лишней интовой переменной и заключается различие, если только одно не будет оптимизировано до другого. Дальнейший код одинаков, но и сама декларация создаёт код, по идее различный, хотя такое различие и не гарантировано.

Добавлено через 6 минут и 15 секунд
Цитата(wowka19 @  12.8.2015,  09:11 Найти цитируемый пост)
В обоих случаях v - имя участка статической памяти под int?
Это тоже не гарантировано, 
Код
void f()
{
 const int v=42;// может быть закодировано в операцию, присваивающую 42 участку стека и запрещать модификацию этого участка
, но в силу константности данной величины, её значение едино для всех экземпляров функции, что и определяет целессобразность оптимизации компилятором 
Код
void f()
{
 const int v=42;
 до 
Код
void f()
{
 const static int v=42;
.

Автор: wowka19 12.8.2015, 09:41
TarasProger, ага, т.е. в случае с int i, временная переменная, созданная для приведения типа, используется для инициализации int i, и тут же удаляется. А как это на стеке выглядит?

Автор: TarasProger 12.8.2015, 09:47
Цитата(wowka19 @  12.8.2015,  09:11 Найти цитируемый пост)
p.s: TarasProger, ничего странного, ибо const гарантирует только невозможность изменить объект только через идентификатор, к которому этот спецификатор (const) добавлен.
Странного то ничего, просто нюанс, понять который можно только подумав конкретно над подобным вот кодом. В случае приведения то i - действительно константа, хоть просто так её декларируй, хоть как ссылку, а без привидения остаётся разрещена модификация через другой идентификатор. И всё правильно, так как в одном случае сущностей две, а в другом одна, но с двумя идентификаторами, имеющими разные свойства. А раз сущность одна, то меняя её через идентификатор переменной, меняем её не зависимо от того, через какой идентификатор будем читать.

Добавлено через 3 минуты и 23 секунды
Код
 const double d = 3.14;
 double &i = d;//Эта строка вообще не валидна.

Автор: TarasProger 12.8.2015, 10:18
Кстати, есть языки, где именованная константа - это просто имя литерала, инлайнящегося по месту использования. То есть 
Код
const a:integer=24;
var b:integer;
    c:integer;
begin
     b:=a;
     c:=a;
 означает просто 
Код
var b:integer;
    c:integer;
begin
     b:=24;
     c:=24;
, значение подставляется на этапе компиялции и адреса не имеет, соответственно указатель на него взять нельзя. А на c++ можно. Константы там - это почти макрсоы, толко строго и статически типизированные и напихать в них операций нельзя. При этом некоторые, например, паскаль, допускают и явную, и неявную типизацию именованных констант.

Автор: wowka19 13.8.2015, 03:52
TarasProger, спасибо, но кажется вы не поняли мой второй вопрос. У меня нет "const int v=42". Продублирую:
Цитата(wowka19 @  12.8.2015,  09:11 Найти цитируемый пост)
Вот еще вопрос:
Вариант 1:
Код

const static int v = 42;

Вариант 2:
Код

const int &v = 42;


В обоих случаях v - имя участка статической памяти под int?
Существует ли код, который ведет себя по-разному в зависимости от варианта определения v?

Автор: TarasProger 13.8.2015, 09:47
А вот как раз 
Код
const int &v = 42;
 и 
Код
const int v = 42;
 - одно и тоже: здесь нет временной величины, так как значение не нужно вычислять, есть обычная глобальная/локлаьная константа и литерал, const в сочетании с меткой декларирует, что 42 должно стать значением временной величины и тут же продляет её существование до обычной локальной/глобальной, так как v нифига не временна, но является синонимом. А staitic гарантировано кладёт её в память рядом с глобальными данными.

Автор: feodorv 13.8.2015, 11:17
Цитата(wowka19 @  12.8.2015,  09:11 Найти цитируемый пост)
В обоих случаях v - имя участка статической памяти под int?

Для глобальной переменной - да. Здесь const подразумевает static. Если, например, в заголовочном файле определить константную строку:
Код

#ifndef xMyHeader
#define xMyHeader

const char v[] = "Very long string";

#endif

то эта строка будет дублироваться в каждом компилируемом файле, который сделал #include "MyHeader". Что может повлечь за собой дополнительные расходы на размер исполняемого файла.

Автор: TarasProger 13.8.2015, 11:40
Код
void f()
{
 static i=2;
}
void d()
{
 static i=4;
}
. Переменные две, но они статик.

Автор: wowka19 17.8.2015, 08:37
Цитата(feodorv @  13.8.2015,  11:17 Найти цитируемый пост)
Для глобальной переменной - да. Здесь const подразумевает static.

feodorv, извините, я наверное уже достал, но у меня static явно указан:
Вариант 1:
Код

const static int v = 42;

Вариант 2:
Код

const int &v = 42;

Что бы расставить все точки:
- в первом варианте в какой памяти находится значение? статической или автоматической(стек)?
- во втором варианте в какой памяти находится значение? статической или автоматической(стек)?
Спасибо!

Автор: TarasProger 17.8.2015, 10:50
Цитата(wowka19 @  17.8.2015,  08:37 Найти цитируемый пост)
Что бы расставить все точки:
- в первом варианте в какой памяти находится значение? статической или автоматической(стек)?
В статической.

Цитата(wowka19 @  17.8.2015,  08:37 Найти цитируемый пост)
- во втором варианте в какой памяти находится значение? статической или автоматической(стек)?
А чёрт его знает. Может и при каждом вызове функции созадаваться на стеке. Но если компилятор оптимизировал этот вариант до первого, тогда в статической. Глобальной видимости не означает ни один из вариантов и если таких констант много в разных функциях, то будет создана каждая. Мало того, даже если равные константы встречаются под разными именами в одной и той же функции, то они и тогда будут продублированы.

Автор: feodorv 17.8.2015, 12:58
Цитата(wowka19 @  17.8.2015,  08:37 Найти цитируемый пост)
но у меня static явно указан

Для константной глобальной (file scope, т.е. определённой вне функции или класса без указания extern) переменной действителен квалификатор static (указан он или нет).

Автор: volatile 17.8.2015, 14:38
Цитата(wowka19 @  17.8.2015,  08:37 Найти цитируемый пост)
- в первом варианте в какой памяти находится значение?

После оптимизации, как в первом, так и во втором случае, константа вообще ни в какой памяти не будет находится.
т.е. под константу не определяется какой-то физический адрес, а значение просто подставляется в код в необходимых местах.
т.е. полный аналог сишного #define v 42

Но это только в том случае, если где либо в программе не встретиться указатель (который нельзя соптимизировать) на эту константу.
В этом случае компилятор будет вынужден разместить ее в статической памяти, и дать ее адрес.

В общем зависит от дальнейшего кода.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)