LINUX.ORG.RU

типы в c

 ,


1

3

есть такая структурка:

struct x { int i; ... char buf[4096 - ???]; };

проблема в размере buf. должно быть так:

static_assert(sizeof(struct x) == 4096);

как написать там нужный размер без боли? очевидный вариант не проходит:

struct x { int i; ... char buf[4096 - offsetof(struct x, buf)]; }; // struct x is incomplete
struct x { struct { int i; ... } y; char buf[4096 - sizeof(y)]; }; // y is undeclared
struct x { struct y { int i; ... } y; char buf[4096 - sizeof(struct y)]; }; //это работает, но как и в предыдущем случае нужно будет писать x.y.i вместо x.i

лучшее, что придумал:

struct x { union { struct { int i; ... char buf[]; }; char _[4096]; }; };

но хочется иметь простой sizeof(buf), а не костылями. есть ли способ?



Последнее исправление: jsforever (всего исправлений: 2)
Ответ на: комментарий от jsforever

Тогда уже никто без С ничего не может потому что ядро написано на C. А еще никто ничего не может без дяди Кости алкоголика, потому что именно дядя Костя открывает вентиль на ТЭЦ которая ток дает в розетку шоб все эти компуктеры работали.

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

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

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

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

можешь попробовать описать структурку из оп на питоне. опустим даже интерпретатор на си - пусть будет в качестве форы. вот нужно взять язык и на нём написать тип.

jsforever
() автор топика
Ответ на: комментарий от jsforever

WTF «написать тип»? Это Вам питонофобия мешает нормально формулировать свои мысли, или у Вас всегда такие сложности?

Можно сделать питоновскую структуру которая умеет дампится в 4096 байт - это вообще без проблем. Только боюсь Вы не этого хотите, точнее судя по топику Вы сами не понимаете чего хотите, и питон с сями тут совершенно непричем.

AntonI ★★★★★
()
Ответ на: комментарий от jsforever

buf будет ссылкой

Учите до просветления как устроены строки в плюсах. Внезапно - в Вашем примере buf тоже указатель, бгггг.

Я же говорю - у Вас большие проблемы с формулированием своих мыслей. Если бы Вы смогли сформулировать внятно что именно Вам требуется от того типа, то наверное Вам бы смогли помочь и в т.ч. питоновское решение предложить. А так простите, все телепаты в отпуске… остается над Вами только глумиться.

ЗЫ кстати в питоне есть нормальная интроспекция, поэтому автоматически что то упаковать и вычислить его размер там вообще одной строчкой делается. Но Вам же так хочется страдать фигней;-)

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 2)
Ответ на: комментарий от AntonI

Внезапно - в Вашем примере buf тоже указатель, бгггг.

нет, не указатель.

Если бы Вы смогли сформулировать внятно что именно Вам требуется от того типа, то наверное Вам бы смогли помочь

не переживай, уже помогли.

остается над Вами только глумиться.

нет, просто ты поплыл в попытке защитить своё божество и теперь пытаешься устроить срач.

jsforever
() автор топика
Ответ на: комментарий от jsforever

нет, не указатель.

То исть Вы не в курсе что сырые строки в С это char *?! Дяденька, учите матчасть.

просто ты поплыл в попытке защитить своё божество и теперь пытаешься устроить срач.

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

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

То исть Вы не в курсе что сырые строки в С это char *?! Дяденька, учите матчасть.

ага. расскажи мне про это скорее.

просто Вы тут начали хамить на ровном месте

показывай.

jsforever
() автор топика
Ответ на: комментарий от jsforever

показывай

нет, просто ты поплыл в попытке защитить своё божество и теперь пытаешься устроить срач.

Для справочки - я на C/C++ пишу 30 лет, это мой основной инструмент. И у меня нет никаких божеств - есть разные инструменты для тез или иных задач.

И еще для справочки - нет, Вам НЕ помогли. Какое смещение будет у buf вот в такой структуре:

struct A{
   int i;
   bool f;
   char buf[4091];
};

Упс?

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

нет, просто ты поплыл в попытке защитить своё божество и теперь пытаешься устроить срач.

это ты показал «Вы тут начали хамить на ровном месте»? а чего же не привёл то, ответом на что это являлось? слишком позорно? а вот я приведу:

остается над Вами только глумиться.

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

И еще для справочки - нет, Вам НЕ помогли. Какое смещение будет у buf вот в такой структуре

ты лучше расскажи мне про указатель, «сырые строки», матчасть и прочее. а то куда-то это всё быстро потерялось. потом уже вопросы.

jsforever
() автор топика
Ответ на: комментарий от jsforever

Тогда как работает это?

#include <stdio.h>

int main( int argc, char* argv[], char* envp[] ){
	
	char buf[32] = "OK, let's go test it!";
	char* p;
	
	for( p = buf; *p; p++ ){
		printf( "%c", *p );
	}
	
	printf( "\nEnd of program.\n" );
	
	return 0;
}

Обрати внимание на p = buf - присвоение без приведения. Рассказывай.

u5er ★★
()
Ответ на: комментарий от u5er

Обрати внимание на p = buf - присвоение без приведения. Рассказывай.

боже. то что там нет явного приведения, не значит, что его там нет вообще.

int x = .5;

рассказывай, как так - дабл в инт присвоился без приведения. так же рассказывай про это, почему в типах там никакого указателя нет, хотя ты выше утверждал обратное.

jsforever
() автор топика
Ответ на: комментарий от jsforever

У Вас с логикой совсем все печально?

- Вашу задачу можно сделать на питоне
- Напиши тип!
- Какой тип?
- Напиши мне тип который мне нада!
- Что он должен делать?
- что тебе не понятно? ты не знаешь что такое тип? напиши мне тип который мне нада!!
- (пишу тип)
- ты фигню написал!!!

ты лучше расскажи мне про указатель

Я Вам лучше примерчик приведу, хотя боюсь с Вашей возможностью усваивать информацию будет не в коня корм.

#include <iostream>

struct A{
   int i;
   bool f;
};
struct B: public A{
   char buf[4091];
};
struct C{
   int i;
   bool f;
   char buf[4091];
};

int main(){
	B b; C c;
	std::cout<<b.buf-(char*)&b<<' '<<sizeof(B)<<'\n';
	std::cout<<c.buf-(char*)&c<<' '<<sizeof(C)<<'\n';
}

$ g++ -Wall -O3   1.cpp && ./a.out
8 4100
5 4096

Но Вы главное не останавливайтесь, Ваш баттхерт доставляет.

А когда полей будет много - уу что начнется! А еще ведь есть разные платформы и разные компиляторы и у них разные уровни оптимизации… наверное мне надо было промолчать, Ваши муки при отладке были бы бесценны.

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

У Вас с логикой совсем все печально?

всё, очередной эксперт кончился? куда там делось хамство на ровном месте? куда делись попытки бездоказательно обвинять меня в чём-то?

Я Вам лучше примерчик приведу, хотя боюсь с Вашей возможностью усваивать информацию будет не в коня корм.

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

jsforever
() автор топика
Ответ на: комментарий от u5er

Товарищ неявно путает понятия устройства данных в памяти и доступа к этим данным. Но главная интрига пока что - шо он собирается делать со структурой которую так старательно упихивает в 4К? Точнее где эти 4К должны проявляться?

Одно дело когда такая штука куда то пишется/пересылается - это можно сделать совсем другими методами. Другое дело когда эта штука должна быть как то в памяти размещена - шо будет если она чуть длинее? Или чуть короче?

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

Я одно время делал свой велосипед.

struct xyt_packed{
	int x:10;
	int y:11;
	int t:11;
};

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

u5er ★★
()
Ответ на: комментарий от u5er

Это совсем другое дело, битовые поля это стандарт ЯП. То что ТС хочет сделать стандартом не описано, ЕМНИП компайлер в своем праве выравнивать поля структуры оставляя между ними дырки и даже переставлять их (cast @bugfixer). Причем разные компайлеры при разных опциях могут это делать по разному.

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от u5er

Обрати внимание на p = buf - присвоение без приведения.

Не-а, ошибочка, без явного приведения.
Отсутствие явного приведения не отменяет автоприведения «голого» имени массива в выражении к указателю на его первый (по смещению 0) элемент.

bormant ★★★★★
()
Ответ на: комментарий от AntonI

ну вот, пытался строить из себя кого-то, а как только спросили конкретику - так он уже устал, да и вообще у него голова сегодня болит. типичный форумный клоун.

jsforever
() автор топика
Ответ на: комментарий от jsforever

Хто ж Вам виноват что Вы при тыкании Вас носом в запрошенную конкретику внезапно разучиваетесь читать? А на пример который показывает что Ваше решение может не работать брыжжете слюной и стучите лысиной по паркету? Я предпочитаю не спорить с людьми которые ведут себя как агрессивные идиоты, времени жалко.

Но глумиться могу, да. Грешен.

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от jsforever

я так понимаю, про указатель и строки я ничего более не услышу, верно?

Простите великодушно, я тут мимо проходил, не сишник ни разу, только иногда касаюсь, не уверен даже что понял верно предмет спора.

На сколько я понял, AntonI и u5er утверждают что buf на самом деле указатель. А вы не согласны. Не могли бы вы сказать мне, что же в данном случае buf на самом деле? (только если можно прямо, без отсылок на код, а то я боюсь не разберусь сразу)

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от AndreyKl

Не могли бы вы сказать мне, что же в данном случае buf на самом деле? (только если можно прямо, без отсылок на код, а то я боюсь не разберусь сразу)

массив, очевидно.

jsforever
() автор топика
Ответ на: комментарий от AntonI

Не хочу разрушать интригу

Спасибо большое, но это ваше мнение. А хотелось бы услышать мнение вашего уважаемого оппонетна в явном виде, чтобы составить собственное мнение.

AndreyKl ★★★★★
()
Ответ на: комментарий от u5er

Ты не объясник, как работает мой пример типы в c (комментарий)

во первых, я объяснил - там неявное преобразование. во вторых, я не вижу объяснений от тебя по поводу моих примеров.

т. е., что мы здесь имеем:

  • наглейшее враньё и просто отрицание реальности
  • попытки приписать оппоненту свои свойства

а теперь беги обясняй мои примеры.

jsforever
() автор топика
Ответ на: комментарий от AndreyKl

На сколько я понял, AntonI и u5er утверждают что buf на самом деле указатель. А вы не согласны. Не могли бы вы сказать мне, что же в данном случае buf на самом деле? (только если можно прямо, без отсылок на код, а то я боюсь не разберусь сразу)

buf — массив (array object).
А спор вызван тем, что в языке Си при упоминании имени массива (buf) в выражении в подавляющем большинстве случаев произойдет конвертация его типа в указатель на начальный элемент массива.
Тем не менее, в остальных случаях разница сохраняется ;)
Простейший пример:

char a[32];  // sizeof a == 32
char *p;  // sizeof p == размер_указателя

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 1)
Ответ на: комментарий от bormant

А спор вызван тем, что в языке Си при упоминании имени массива (buf) в выражении в подавляющем большинстве случаев произойдет конвертация его типа в указатель на начальный элемент массива.

гм.. может я очень хорошо понимаю тему если я не более чем в 11 классе..

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

// прям даже самому любопытно стало, но не лезть же читать про этот ваш си...

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от u5er

На самом деле ТС кое в чем прав - с т.з. компилятора сырой массив это указатель + информация о размере массива. С т.з размещения данных в памяти вообще спорить не о чем char buf[N] и char *ptr вещи разные.

Но хочу напомнить с чего начался весь сыр-бор - у ТС была претензия к питону что там строка это ссылка (сиречь указатель). Но вообще то в питоне ВСЕ является ссылками, а в сишечке синтаксически что со ссылками работать, что напрямую с обьектами - разницы нет.

И мы возвращаемся к тому что именно хочет ТС сделать. И вот тут (повангую) мы услышим от него много криков но никакой конкретики - потому что ТС сам не понимает что именно он хочет учудить.

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от jsforever

кроме эникеев, случайно оказавшихся номинально программистами

ну, нам сложно бывает, да.

а не поясните разницу между массивами и указателями в си, а то я запутался немного.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

так а зачем тебе это, эникей? накат маздайки подобных знаний не требует.

но в целом, показательно - прибежала макака из группы поддержки и пытается меня заспамить дешёвой клоунадой.

jsforever
() автор топика
Ответ на: комментарий от jsforever

пытается меня заспамить дешёвой клоунадой.

Я пытаюсь понять разницу между массивами и указателями. Может быть поясните всё таки?

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от jsforever

Так а смысл? Я попытался донести до тебя свою мысль, но у меня не получилось и я сел в лужу, да. Может быть потом я ещё раз попробую, а может и нет, но пока что хватит.

u5er ★★
()
Ответ на: комментарий от AndreyKl

когда при упоминании имени массива (buf) в выражении в НЕ произойдет конвертация его типа в указатель на начальный элемент массива?

Это можно, но сложно. Синтаксис наркоманский и боюсь ТС такое не проходил (это уже за пределами школы):

template <typename T, int D> bool f(T const (&p)[D]){ ... }
...
char buf[123];
f(buf); // <=== хоба! массиф осталься массифом!!!
AntonI ★★★★★
()
Ответ на: комментарий от AndreyKl

Цитата из стандарта C23 (N3054)

6.3.2.1.3
Except when it is the operand of the sizeof operator, or typeof operators, or the unary & operator or is a string literal used to initialize an array, an expression that has type «array of type» is converted to an expression with type «pointer to type» that points to the initial element of the array object and is not an lvalue.
If the array object has register storage class, the behavior is undefined.

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 2)
Ответ на: комментарий от AntonI

Крутой пример. Старался-старался понять что тут написано...

так, ну тип T. Т const (&p) - константная ссылка на тип T. D размер массива. Т.е. мы пытаемся взять ссылку на массив определённого размера?

AndreyKl ★★★★★
()
Ответ на: комментарий от jsforever

типы в c (комментарий)

Интересно, сколько раз мне это придется повторить что бы до Вас дошло? Я понимаю что с Вашей дислексией путь даже в техподдержку заказан, но и разработчик из Вас при таких способностях к восприятию информации не очень прям скажем… Впрочем на ЛОРе забавлять народ у Вас неплохо получается.

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

типы в c (комментарий)

Внезапно - в Вашем примере buf тоже указатель, бгггг.

типы в c (комментарий)

То исть Вы не в курсе что сырые строки в С это char *?! Дяденька, учите матчасть.

повторять придётся долго, но уже себе.

jsforever
() автор топика
Ответ на: комментарий от AntonI

сколько раз мне это придется повторить что бы до Вас дошло?

Мне кажется, что его проблема в том, что он не пытается даже вникнуть в то, что ему пишут :)

u5er ★★
()
Ответ на: комментарий от AntonI

Т.е. когда я написал

bool f(int *p) { return p[10]; }

я хоть и обратился к нему как к массиву, но уже будет просто арифметика указателей использоваться, а sizeof(p) даст мне просто размер указателя на инт? Хотя выглядит всё вполне пристойно?

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от jsforever

тут неявно путается два понятия - способ выделения памяти под данные и способ обращения к этим данным.

Перечитывайте эту фразу до просветления. Если непонятны какие то термины - обратитесь к своему школьному учителю по программированию. Значение остальных слов, включая предлоги, Вам сможет объяснить Ваш школьный учитель по русскому языку.

Я верю что к концу этого учебного года Вы сможете понять о чем шла речь! Главное не сдавайтесь!!

AntonI ★★★★★
()
Ответ на: комментарий от AndreyKl

Да. Причем Вы не знаете p[10] еще в массиве лежит или где то за его пределами. Если за пределами в лучшем случае будет сегфолт, в худшем UB и замучаетесь с отладкой.

Но если уверены что в p больше 10 элементов все нормально;-)

собственно std::array отчасти решает эти проблемы. Минус - задолбаешься в компайл тайм везде размеры массива протаскивать…

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 2)
Ответ на: комментарий от AndreyKl

я хоть и обратился к нему как к массиву

С чего вдруг такой поспешный вывод?
[] — это синтаксический сахарок для арифметики указателей, a[ b ] — это
*(a+b), если a — массив, b — целое
*(b+a), если b — массив, a — целое (угу можно и так: 10[ p ]).

PS. На самом деле как к массиву, но не из-за [], а из-за того что арифметика указателей вне массива — UB ;)

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 3)
Ответ на: комментарий от jsforever

На самом деле вы зря спорите.

buf будет ссылкой

Учите до просветления как устроены строки в плюсах. Внезапно - в Вашем примере buf тоже указатель, бгггг.

Отсюда явно видно что вы просто не понимали что в питоне ссылки - это примерно то же что указатели в си. Или даже примерно то же что массивы в си. Массивы конечно хранят дополнительно размер (как мы тут выяснили, благодаря AntonI и bormant). Ну так вангую что и ссылки в питоне что то дополнительно хранят.

Вряд ли вы понимали эти детали когда утверждали что массивы в си и ссылки в питоне не одно и то же. По крайней мере по вашим примерам этого не очень видно. По крайней мере мне.

Мне кажется АнтонИ верно вам написал насчёт того что вы путаете способ хранения и способ обращения. Но это норм. Нужно обратить внимание и разобраться получше.

Успехов.

AndreyKl ★★★★★
()
Ответ на: комментарий от bormant

С чего вдруг такой поспешный вывод?

ну потому что он обратился к нему как к массиву;-)

Второй вариант b[a] меня вымораживает напрочь до сих пор, отцы-основатели были большими затейниками…

Но

int i[12], buf=2;
...
buf[i]

Это же какие возможности для обфускации кода!

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

Да. Причем Вы не знаете p[10] еще в массиве лежит или где то за его пределами. Если за пределами в лучшем случае будет сегфолт, в худшем UB и замучаетесь с отладкой.

ну, всё не настолько плохо)

за пояснения спасибо, особенно за пример с протаскиванием массива.

собственно std::array отчасти решает эти проблемы. Минус - задолбаешься в компайл тайм везде размеры массива протаскивать…

Ну я просто вектор по ссылкам таскаю...

AndreyKl ★★★★★
()
Ответ на: комментарий от bormant

PS. На самом деле как к массиву, но не из-за [], а из-за того что арифметика указателей вне массива — UB ;)

а из-за того что арифметика указателей вне массива — UB

вот это совсем не распарсил..

Смутно вспоминаются манипуляции с полученным void* и вычислением смещения по известному размеру. Это что всё стыдноUB?

AndreyKl ★★★★★
()
Ответ на: комментарий от AntonI

ты что ранее рассказывал? - char[n] является char*, массив является указателем. т. е. о том, что никаких различий нет. далее ты загуглил и обнаружил различия между массивом и указателем, но чтобы отмазаться, начал говорить «это не та разница», «эта разница не считается». только не учёл, что в случае отношения «является» любая разница опровергает эквивалентность.

jsforever
() автор топика
Ответ на: комментарий от AndreyKl

Смутно вспоминаются манипуляции с полученным void* и вычислением смещения по известному размеру. Это что всё стыдноUB?

Как только вылезут за пределы object, так сразу и.

C23 (N3054)

6.5.6 Additive operators
8 For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.
9 ... If the pointer operand and the result do not point to elements of the same array object or one past the last element of the array object, the behavior is undefined.

bormant ★★★★★
()
Ответ на: комментарий от AndreyKl

Отсюда явно видно что вы просто не понимали что в питоне ссылки - это примерно то же что указатели в си. Или даже примерно то же что массивы в си.

Или даже примерно то же что массивы в си.

указатель то же что массивы

да, ты совсем не палишься, эникей. я тебе уже говорил - накатывай маздайку, зачем ты лезешь куда-то?

Вряд ли вы понимали эти детали когда утверждали что массивы в си и ссылки в питоне не одно и то же

и снова то же самое.

Мне кажется АнтонИ верно вам написал насчёт того что вы путаете способ хранения и способ обращения

ну меня мало интересует, что там кажется эникею. с чего вдруг видения некомпетентного юнита стали аргументом?

jsforever
() автор топика
Ответ на: комментарий от jsforever

Вы пожалуйста держите при себе свои проекции. А то Вы себе что то придумали и как давай обижаться что реальность с Вашими фантазиями некоррелирует!

Когнитивные способности — это совокупность мозговых процессов, участвующих в познании окружающего мира. С их помощью человек воспринимает, обрабатывает, сортирует, запоминает, хранит и воспроизводит информацию. 

К когнитивным способностям относятся: 

1)    Восприятие. Совокупность психических процессов, которые отвечают за отражение в сознании образов предметов, непосредственно воздействующих на органы чувств. 
2) ...

Там пунктов много, у Вас с восприятием прям беда-беда.

AntonI ★★★★★
()
Ответ на: комментарий от AndreyKl

Мне кажется АнтонИ верно вам написал насчёт того что вы путаете способ хранения и способ обращения.

Да. Точно кажется, и в части «верно», и в части «способов».

bormant ★★★★★
()
Ответ на: комментарий от AntonI

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

ты иди объясняйся за вопросы, на которые ответить не смог. как так вышло?

jsforever
() автор топика
Ответ на: комментарий от bormant

Как только вылезут за пределы object, так сразу и.

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

AndreyKl ★★★★★
()
Ответ на: комментарий от bormant

Перечитал тред, обдумал эту мысль. Вероятно вы правы, jsforever скорее всего действительно знал что массивы имеют длину и хранят её где то. Спасибо за поправку.

jsforever если это так, выходит в этом случае я хорошо знаю тему для одиннадцатиклассника. За сим в данный спор больше не лезу.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

sizeof(p) даст мне просто размер указателя

раз уж p указатель, то размер указателя и даст sizeof(p).

Если бы хотелось, чтобы p был указателем на массив из 10 элементов int, то:

int (*p)[10];

sizeof(p) == размер указателя,
sizeof(*p) == sizeof(int)*10 (тоже случай сохранения размера массива времени компиляции).

bormant ★★★★★
()
Ответ на: комментарий от FishHook

Нигде не хранят, длина массива задаёт его типом.

В нормальных языках типа раста хранят

Нет конечно, в расте массивы имеют константный размер времени компиляции. Ты путаешь со слайсами и heap-allocated контейнерами типа vec.

theNamelessOne ★★★★★
()
Ответ на: комментарий от theNamelessOne

Нет конечно, в расте массивы имеют константный размер

разумеется, я и не утверждал обратного

fn len_of_slice(slice: &[i32]) -> usize {
    slice.len()
}


fn main() {
    let array = [1, 2, 3, 4, 5];
    println!("The length of the array is: {}", array.len());
    println!("The length of the sliсe is: {}", len_of_slice(&array));

}

что массив, что ссылка на массив имеют доступ к своему размеру в рантайме. Именно это я и имел в виду говоря, что массивы в раст хранят свой размер.

FishHook
()
Ответ на: комментарий от unC0Rr

В этом смысле и в Си х ранят,

нет в этом смысле и каком-либо другом смысле не хранят, именно поэтому вы постоянно выходите за границы массивов и буфферов. Попробуйте обратиться к несуществующему индексу массива в расте. Как по-вашему происходит выброс исключения если раст не хранит размер? А вот си ничего не выбрасывает и вы можете делать ptr++ сколько влезет, пока ОС не пристрелит

FishHook
()
Ответ на: комментарий от FishHook

нет в этом смысле и каком-либо другом смысле не хранят

В этом смысле хранят, например, указатель на массив массивов p++ инкрементируется длиной массива.

поэтому вы постоянно выходите за границы массивов и буфферов. Попробуйте обратиться к несуществующему индексу массива в расте.

В си нет механизма проверки границ массива, в расте есть. Разница в этом, а не в «хранении» размера массива.

unC0Rr ★★★★★
()
Ответ на: комментарий от unC0Rr

В этом смысле хранят, например, указатель на массив массивов p++ инкрементируется длиной массива.

что? инкрементируется длиной массива? Это как? ЛОЛ

В си нет механизма проверки границ массива, в расте есть. Разница в этом, а не в «хранении» размера массива.

как по-вашему происходит проверка границ массива, если размер массива не «хранится»?

FishHook
()
Ответ на: комментарий от FishHook

Это как?

#include <stdio.h>

int main() {
    // Define a 2D array with 3 rows and 4 columns
    int array[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };

    // Pointer to the entire array of 4 integers (one row)
    int (*ptr)[4] = array;

    printf("Initial pointer address: %p\n", (void*)ptr);

    // Iterate over each row using the pointer
    for (int i = 0; i < 3; i++) {
        printf("Row %d address: %p\n", i, (void*)ptr);
        printf("First element of row %d: %d\n", i, (*ptr)[0]);

        // Increment the pointer to point to the next row
        ptr++;
        printf("Pointer incremented to: %p\n\n", (void*)ptr);
    }

    return 0;
}

как по-вашему происходит проверка границ массива, если размер массива не «хранится»?

Размер массива «хранится», а не хранится. Нет области памяти или переменной с размером массива, которая будет являться частью массива. Компилятор знает размер массива из его типа, и может подставлять его в нужных местах, например, при копировании массива или проверки индекса. Этот размер есть в программе как часть кода программы, а не часть данных, которые программа обрабатывает.

unC0Rr ★★★★★
()
Ответ на: комментарий от FishHook

Вообще, размер массива хранится в том же смысле, в каком в программе хранится размер int или какой-нибудь структуры. Как в расте, так и в си, никакой разницы.

unC0Rr ★★★★★
()
Ответ на: комментарий от unC0Rr

Нет области памяти или переменной с размером массива, которая будет являться частью массива. Компилятор знает размер массива из его типа, и может подставлять его в нужных местах, например, при копировании массива или проверки индекса

есть такая область. В расте нельзя взять просто указатель на массив, вы всегда будете иметь пару указатель + длина массива. А поскольку любые операции с массивом вы производите через указатель на него, у вас всегда будет длина массива сохраненная именно в памяти как часть указателя.

FishHook
()
Ответ на: комментарий от FishHook

В расте нельзя взять просто указатель на массив

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f44b06360634625ba4c59671e9e135a2

вы всегда будете иметь пару указатель + длина массива

fat pointers используются в случаях, когда длина типа неизвестна на этапе компиляции, например dyn типы или слайсы.

unC0Rr ★★★★★
()
Ответ на: комментарий от FishHook

вы же хотели сказать размером элемента массива, да же?

Массив двумерный, элемент массива является массивом, вот длину «внутреннего» массива я и имел в виду.

unC0Rr ★★★★★
()
Ответ на: комментарий от unC0Rr

fat pointers используются в случаях, когда длина типа неизвестна на этапе компиляции, например dyn типы или слайсы.

Вы капитаноочевидные вещи выдаете за откровение. Я в общем-то об этом и говорю с самого своего первого поста - раст прозрачно для программиста сохраняет информацию о длине массива, когда информация о типе стирается в рантайме. Если вы пишите безопасный код, длина массива всегда доступна. Можете называть это как угодно, но по русски это звучит как «раст хранит информацию о длине массива».

FishHook
()
Ответ на: комментарий от FishHook

Напомнить, с чего начинался тред? Я сказал, что длина массива нигде не хранится, а задаётся типом. На что вы отвечаете, что в расте хранится, что по логике беседы должно противопоставлять си и раст. Но по факту ситуация одинаковая, с точностью до отсутствия в си слайсов, трейтов и проверки границ.

Информация о длине массива существует только в компайл-тайме. Компилятор раста использует это знание для формирования слайсов и проверки границ, но это ровно то же самое, что происходит, когда мы пишем ptr++ в сишном примере.

unC0Rr ★★★★★
()
Ответ на: комментарий от unC0Rr

 Но по факту ситуация одинаковая… это ровно то же самое, что происходит, когда мы пишем ptr++ в сишном примере.

прошу вас, воспроизведите на Си вот такой код

fn total(a: &[&[i32]]) -> usize {
    return a.into_iter().map(|x| x.len()).sum()
}

const RANDOM: i32 = 3;

fn main() {
    let a = [1, 2, 3, 4];
    let b = [4, 5];
    let c = [5, 6];
    let d = [1, 2, 3];
    println!("{}", total(&[&a, &b, if (RANDOM % 2 == 0) {&c} else {&d}]));
}

FishHook
()
Ответ на: комментарий от unC0Rr

Слайсы хранят свою длину, не массивы

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

FishHook
()
Ответ на: комментарий от unC0Rr

до отсутствия в си слайсов, трейтов и проверки границ.

вот в этом и отличие. Вы же на просьбу воспроизвести мой пример на си отвечаете «В си нет слайсов. Слайсы хранят свою длину, не массивы», значит разница ломающая подход к написанию кода есть и она не дает вам возможности переписать растовый код на си. Где бы эта самая длина не хранилась, она хранится, и раст делает это сохранение прозрачно и невидимо, пусть даже там под капотом юзается sizeof. Ну вперед, пожалуйста, заюзайте силу sizeof, чтобы мой пример стал работать на си.

FishHook
()
Ответ на: комментарий от FishHook

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

unC0Rr ★★★★★
()
Последнее исправление: unC0Rr (всего исправлений: 1)
Ответ на: комментарий от FishHook

Ну и да, вот вам эквивалентный код от чатгпт, как видим никакой ломающей разницы, просто разные типы слайсов приходится определять отдельно, как и заполнять их приходится вручную:

#include <stdio.h>
#include <stddef.h>

// Define a Slice struct to hold a pointer to an array and its length
typedef struct {
    int *data;
    size_t len;
} IntSlice;

// Define a SliceSlice struct to hold an array of Slice structs and its length
typedef struct {
    IntSlice *data;
    size_t len;
} SliceSlice;

// Function to calculate the total length of all slices
size_t total(SliceSlice slice_slice) {
    size_t sum = 0;
    for (size_t i = 0; i < slice_slice.len; i++) {
        sum += slice_slice.data[i].len;
    }
    return sum;
}

// Define the RANDOM constant
const int RANDOM = 3;

int main() {
    // Initialize the arrays
    int a[] = {1, 2, 3, 4};
    int b[] = {4, 5};
    int c[] = {5, 6};
    int d[] = {1, 2, 3};

    // Create an array of Slice structs
    IntSlice slices[3];

    // Assign the first slice
    slices[0].data = a;
    slices[0].len = sizeof(a) / sizeof(a[0]);

    // Assign the second slice
    slices[1].data = b;
    slices[1].len = sizeof(b) / sizeof(b[0]);

    // Determine which slice to use based on RANDOM
    if (RANDOM % 2 == 0) {
        slices[2].data = c;
        slices[2].len = sizeof(c) / sizeof(c[0]);
    } else {
        slices[2].data = d;
        slices[2].len = sizeof(d) / sizeof(d[0]);
    }

    // Create a SliceSlice struct to hold the array of slices
    SliceSlice slice_slice;
    slice_slice.data = slices;
    slice_slice.len = 3;

    // Calculate the total length
    size_t total_length = total(slice_slice);

    // Print the result
    printf("%zu\n", total_length);

    return 0;
}
unC0Rr ★★★★★
()
Ответ на: комментарий от FishHook

разница ломающая подход к написанию кода есть и она не дает вам возможности переписать растовый код на си

Чувак, ты иногда поражаешь своим «могучим» интеллектом. Дам тебе подсказку. То что можно написать на одном тьюринг полном языке, можно написать и на другом. Гугли в эту сторону, не позорься.

PRN
()
Ответ на: комментарий от PRN

Ты дебил, который видит в тексте реперные точки и как попугай реагирует, не утруждая себя размышлениями, а что же имел в виду автор.

FishHook
()
Последнее исправление: FishHook (всего исправлений: 1)
Ответ на: комментарий от FishHook

Ты дебил…

Ты чуешь чем пахнет? Снова горелым беконом))

… в тексте реперные точки …

Знаешь, если в текст пихать умные слова, то для кого-то он может показаться умнее, но это только для кого-то и только кажется. От умных слов эта глупость умнее не стала)

… что же имел в виду автор

Что имел в виду автор, понятно из текста, т.к. автор не Эйнштейн и может, разве что, разбавить свой текст умными словами не к месту))

PRN
()