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)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

показывай.

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

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

char buf[32];

buf - это указатель на первый элемента массива. Память выделяется на стеке в пределах области видимости.

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

показывай

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

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

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

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

Упс?

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

buf - это указатель на первый элемента массива

нет. возьми, проверь - изи же:

char buf[8];
static_assert(__is_same(decltype(buf), char[8]));
static_assert(!__is_same(decltype(buf), char*));
jsforever
() автор топика
Ответ на: комментарий от 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 ★★★★★
()

Если кто ценит кошмарные Си-шные макросы:

#include <stdio.h>

#define INSBUF(prev, buftype, bufname, sz, post) {\
  prev \
  buftype bufname[ (sz - sizeof(struct{prev}) - sizeof(struct{post}) ) / sizeof(buftype) ];\
  post \
}

struct str INSBUF(
  int a;
  float b;
  char c[10];
  ,
  int, buf, 100,
  
  int z;
  float y;
  char x[20];
);

int main(){
  struct str aaa;
  printf("%i\n", (int)sizeof(aaa.buf));
}
$ gcc main.c -Os -Wall -Wextra
$ ./a.out 
52

Не то чтобы смотрелось менее вырвиглазно, чем union, зато буфер можно вставлять в середину

COKPOWEHEU
()
Ответ на: комментарий от 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

а как только спросили конкретику - так он уже устал

Может потому, что ты сразу соскакиваешь с темы? Как в моём случае, например.

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

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

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

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

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

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

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

Может потому, что ты сразу соскакиваешь с темы? Как в моём случае, например.

так показывай соскок.

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

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

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

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

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

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

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

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

Я понял, благодарю. Мне кажется вы правы и спорить с тем что buf - массив, довольно таки бессмысленно.

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

Осталось понять чем (и когда!) массив отличается от указателя на первый элемент массива;-)

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

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

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

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

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

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

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

простите, ещё один вопрос: а в каком вы сейчас классе?

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

AndreyKl ★★★★★
()
Ответ на: комментарий от 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)
Ответ на: комментарий от AndreyKl

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

jsforever
() автор топика
Ответ на: комментарий от 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

боже, ты там загуглил чтоли? ты же рассказывал про «массив является указателем», а тут вдруг это уже разное?

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

Большое спасибо за цитату, что то такое вспоминается конечно со второго курса, но как то краешком памяти.

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

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

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

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

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

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

AntonI ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.