
Dmitry
21.01.2017
12:46:55
Все, посидел поыткал дошло как с указателями работать
Вопрос на засыпку. Я правильно понимаю что указатели позволяют только в пределах адресного проснтранства приложения к адресам образаться? Возможно ли обращение за пределы адресного пространства приложения?
Ребят, вопрос:
char [] str = "aaa".dup;
char [] *str_ptr;
writeln(str_ptr);
str_ptr = &str; // получается я массиву указателей присваиваю ссылку? Т.е. str_ptr[0] будет содержать &str

Max
21.01.2017
15:27:27

Google

Max
21.01.2017
15:28:00

Dmitry
21.01.2017
15:29:14
str_ptr[0] = &str; ругается:
Error: cannot implicitly convert expression (& str) of type char[]* to char[]
writeln(str_ptr[0][1]);
@deviator а вот куда у меня тут поинтеры ссылаются?
char [] str = "aaa".dup;
char [] * str_ptr = &str; // pointer to array
writeln((str_ptr[0]).ptr);
writeln((str_ptr[1]).ptr);
writeln((str_ptr[2]).ptr);
Вывод:
> app.exe
2731010
19FE60
1
Адрес и указатель это синонимы?

Oleg
22.01.2017
16:17:59
Указатели, которые ты там разыменовываешь никуда не ссылаются, кроме первого, вообще так делать не надо
Адрес хранится в указателе
Это не синонимы

Dmitry
22.01.2017
16:22:01
т.е. указатель это тип, а разыменование это превращение _адреса_ в символ так?
А рвзе в D уrазатели по умолчанию в null инициализируются?
int *z;
writeln(z);
null выводит

Oleg
22.01.2017
17:33:08
Да, по умолчанию null

Dmitry
23.01.2017
07:09:00
А чем отличается ключевое слово ref от &
как я понимаю я могу записать
int x = 4;
foo(x);
foo(&x) {}

Google

Армен
23.01.2017
07:49:12
& - это взятие адреса переменной, а объект с реф - ссылка сама по себе. Ты не сможешь присвоить указателю ref i, а &i сможешь

Dmitry
23.01.2017
07:54:39
foo (ref x) { } что делает?

Армен
23.01.2017
08:05:20
Принимает ссылку на объект x

Dmitry
23.01.2017
08:06:09
а если foo(&x) написать?

Армен
23.01.2017
08:10:17
ref ты пишешь в определении, не во время вызова. foo(ref int x) {} - ты должен указать и тип принимаемого значения. А чтобы вызвать: int i; foo(i).
Даже если у тебя так foo(int *x), ты не можешь вызов написать как foo(ref x), потому что реф - это ссылка, а не адрес переменной. Чтобы передать указатель, ты напишешь foo(&x)
реф не берет адрес переменной, он говорит при объявлении "тут будет ссылка, а не значение"

Oleg
23.01.2017
08:28:12
И еще важный момент: ссылка и указатель, хоть и похожи - разные вещи, не надо путать

Dmitry
23.01.2017
08:28:56
ссылку компилятор как-то сам разруливает?

qwe
23.01.2017
08:28:58
@DmitryBubnenkov void foo(int &x) {} нельзя писать

Oleg
23.01.2017
08:29:31
@DmitryBubnenkov не понял
Компилятор сам много чего разруливает
Что именно он делает со ссылкой по твоему?

Dmitry
23.01.2017
08:31:09
ну вот я пишу calc(ref int x) компиялтор сам поймет что нужно найти адрес перемнной и работать с ним как со значением?

qwe
23.01.2017
08:33:03
да

Армен
23.01.2017
08:33:03
Это ты так пишешь функцию. При вызове передаешь ей переменную, и функция берет ссылку на нее, а не значение

Dmitry
23.01.2017
08:33:45
а почему всегда нельзя ref использовать? Ведь вроде как это удобнее

qwe
23.01.2017
08:34:28

Dmitry
23.01.2017
08:34:50
qwe а in что делает?

qwe
23.01.2017
08:35:06
означает, что аргумент не будет изменен
и еще что-то)

Google

Dmitry
23.01.2017
08:35:45
в смысе не будет изменен? Я значение оригинальное поменять не смогу?

qwe
23.01.2017
08:35:55
внутри функции нет
так
Лафоре С++ читали?

Dmitry
23.01.2017
08:36:50
нет

qwe
23.01.2017
08:37:40
Почитайте. Доступным языком написано. Все можете не читать, если понимаете о чем речь. Но главу про указатели и ссылки прочтите обязательно
Я на I курсе тоже не мог понять что к чему. С этой книгой разобрался. И не ленитесь написать какую-нибудь программку, которая покажет, что есть что.
на rutracker есть

Dmitry
23.01.2017
08:39:33
да я вот сейчас сижу энергично разбираюсь с этим всем

qwe
23.01.2017
08:41:08
Вы сейчас энергично вопросы задаете и получаете ответы, собирая puzzle. Возьмите книгу и последовательно разберитесь. Проблема не в том, что Вы задаете вопросы, а в том, что получая ответы, не получаете знания

Dmitry
23.01.2017
08:59:41
qwe я почитал про эту тему. Ты написал что можно писать in ref, но по идее in показывает, что мы берем данные и не можем их менять. т.е. используем как ссылку для обработки (когда оригинал трогать не надо) т.е. in ref писать нельзя, а только foo(in int x)

Oleg
23.01.2017
09:07:31
"т.е. используем как ссылку для обработки", насколько я помню, это не верно

Oleg
23.01.2017
09:07:42
in это только то что мы эти данные менять не можем
ссылкой они от in не становятся

Dmitry
23.01.2017
09:10:30
если мы передаем в функцию данные, то работаем с их копией и оригинал и без всяких in менять не можем, разве не так?
Как я понял ref это чисто дишная обертка, которая позволяет избежать работу с указателями?

Oleg
23.01.2017
09:17:20
в С++ тоже есть ссылки, во многих языках они есть, но по другому просто указываются
классы в D передаются только по ссылке
там удобно использовать in
динамические массивы тоже можно защищать с помощью in

Google

Oleg
23.01.2017
09:18:27
хотя это не ссылка

Dmitry
23.01.2017
09:20:59
а касательно модификаторы in. чnо он защащает то? Если бы он защищал ссылочные данные, то было бы понятно, а так получается что с ним вроде как происходит та же операция копирования

Армен
23.01.2017
09:27:15

Dmitry
23.01.2017
09:28:38
а почму бы как const их не объявлять тогда?

Oleg
23.01.2017
09:39:25
https://dlang.org/spec/function.html#parameters
in это тоже что const scope
только букав меньше)
и не все параметры можно передать как ссылку

Admin
ERROR: S client not available

Oleg
23.01.2017
09:42:13
взять ссылку результата вычислений не получится
т.е.
void func(ref int x) { ... }
void main() {
func(1+4); // не сработает
int x = 1 + 4;
func(x); // ссылку на x можно взять
}
чтобы это обойти можно использовать auto ref шаблонные функции
void func()(auto ref int x) { ... }
void main() {
func(1+4); // теперь будет работать, передастся значение
int x = 1 + 4;
func(x); // по прежнему по ссылке будет работать
}
это будет удобно при работе со структурами, которые не хочется копировать, но иногда не удобно создавать промежуточные переменные, чтобы по ссылке передавать
void func()(auto ref const Vector!500 v) { ... }
если будет передаваться какая-то уже существующая переменная, то будет взята её ссылка, если это будет результат функции, то он передастся по значению

Армен
23.01.2017
10:03:23

Oleg
23.01.2017
10:10:26
вроде нет
отдельного механизма для rvalue я не помню
для ссылок на rvalue
да и зачем они нужны?

Google

Oleg
23.01.2017
10:11:08
это не самое сложное, что может сожрать оптимизатор
мне кажется вычисленное rvalue значение сразу попадает в стек функции вызываемой, по сему не вижу смысла в rvalue ref
но, с другой стороны, хук с auto ref не очень то красив
потому как в интерфейсах и классах заставляет дублировать функции

Армен
23.01.2017
10:12:52
Ну вообще да, даже в С++ рекомендуют rvalue не трогать, компиляторы сами оптимизируют

Oleg
23.01.2017
10:13:30
class A {
final void func()(auto ref int x) {
_func(x);
}
abstract void _func(ref int x);
}
если бы auto ref не требовал шаблонизации было бы вообще шоколадно
хотя если оптимизатор бы умел (мы были бы в этом однозначно уверенны) не копировать значение для const значений, то эта фича вообще не нужна была бы
надо будет задать по этому поводу вопрос на форуме

Армен
23.01.2017
10:16:46
А чем плоха шаблонизация? Если передать и ссылку и значение программе, то будет два варианта функции - это подразумевается под дублированием?

Oleg
23.01.2017
10:21:09
шаблонную функцию нельзя наследовать
или сделать абстрактным методом класса/интерфейса
если она метод структуры, то всё ок
там наследования нет

Dmitry
23.01.2017
12:56:24
А есть какой-то способ просмотреть поля(свойства какого-то типа данных. К примеру массива. чтобы глазами увидеть какие там вещи есть sizeof и тд

Grigirii
23.01.2017
12:59:26
https://dlang.org/phobos/std_traits.html#FieldNameTuple
это выдаст все свойства объекта
правда всякие sizeof как раз не даст
потому что это у всех есть, а не специфично для твоего типа

Dmitry
23.01.2017
13:01:28
В примере ему передают созданный тип, а как к примеру посмотреть что есть у статического массива?
так же писать нельзя: writeln(FieldNameTuple![3]);