LINUX.ORG.RU

Можно ли в Си управлять размещением переменных как в ObjectPascal?

 ,


0

1

Вот в Delphi (FreePascal) есть такая директива absolute

var
   a:array[1..10] of integer;
   b:String absolute a;

....

В результате компилятор разместит переменные a и b по одному адресу. Это очень удобно для разных нетривиальных преобразований типов, когда они запрещены напрямую.

Другой способ: поля в записях record, вроде такого

type TMyRecord = record
case Boolean of  //Вместо Boolean можно писать любой перечислимый тип, это не контролируется
    1: (i: Int64);
    2: (a1: byte; a2: byte; a3: byte; a4: byte; a5:byte; a6:byte; a7:byte; a8:byte);
end;

var 
   M:TMyRecord;

M.a2 = // Доступ к 2-му байту представления i.

Понятно, что можно завести указатели на переменные и присваивать им различные адреса, но это дополнительная операция, а вот как чтобы сразу компилятор размещал переменные в одном месте. Между прочим, в Borland Pascal, которые еще для MS-DOS, можно было в absolute даже адрес памяти указать, сейчас нельзя так как это было актуально только в реальном режиме.

★★★★★

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

А конкретный пример?

Конкретный пример получения адреса переменной? :)

Я делал что-то вроде такого, не помню уже для чего и какие с этого профиты были

char array[100];

int a __attribute__((at(array))) = 100;
grimwaken
()
Ответ на: комментарий от thesis

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

anonymous
()

пискалисты пихают системщину куда не надо. за такое расстреливают на месте. юзай дотнетовский маршаллинг, убогое

anonymous
()

https://en.wikipedia.org/wiki/Bit_field#C_programming_language

((stuct what_u_wona)&place)->fild_as_u_wish

ps. в староСях обмазывание «строгим типизированием» было не обязательно хватало adress->anything_that_u_whona_read_as_somthing_of_some_type_and_offset_from_point

anonymous
()

Канешно можно. Или тибю про полноту по Тьюрингу не слышал? ЗЫ Если действительно не слышал, то обязательно вышлю в твою деревню ящик бананов в качестве гум. помощи. Пиши до востребования с пометкой #гум.помощь.хелп на адрес ближайшего районного Главпочтампта.

anonymous
()
Ответ на: комментарий от ya-betmen

Почему б нет?

#define COLOR_ARR_A (0)
#define COLOR_ARR_B (1)
#define COLOR_ARR_G (2)
#define COLOR_ARR_R (3)

typedef struct
{
   u8 rgba[4];
} color_arr_rgba;

typedef struct
{
   u8 a;
   u8 b;
   u8 g;
   u8 r;
} color_str_rgba;

typedef union
{
   color_str_rgba str;
   color_arr_rgba arr;
   u32            quad;
} color_t;


<...>

color_t pixel = { 0 };
pixel.str.r = 0x50;
pixel.str.g = 0x45;

pixel.arr.rgba[COLOR_ARR_R] = 0x50;
pixel.arr.rgba[COLOR_ARR_G] = 0x45;

pixel.quad = 0x00004550u;

Или вы про что?

PPP328 ★★★★★
()
Ответ на: комментарий от ya-betmen

Ну тогда не ясно чего ТС не хватает.

Если есть f(color_str_rgba a), то не очень ясно сработает ли в ней color_t &b = a.

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

color_t &b = a.

Не распарсил. У вас точно lvalue не перепутано?

Если функция принимает color_str_rgba, а внутри функции вы кастуете ее к color_t, то все будет работать (в данном случае), ибо все три типа одного размера. Плюс все три типа указывают на один адрес, так что побарабану как вы интерпретируете тип - 4 байта они и в африке 4 байта, можете хоть к строке его кастануть и присвоить:

void print_color(color_t * c)
{
    printf("Color is 0x%08x\n", c->quad);
}

void assign_via_ass(color_arr_rgba a)
{
    char * str = (char *)&a;
    
    printf("%s\n", str);
    print_color((color_t *)str);
}

int main()
{
    color_arr_rgba a;
    a.rgba[0] = 0x48;
    a.rgba[1] = 0x69;
    a.rgba[2] = 0x21;
    a.rgba[3] = 0x0;
    
    assign_via_ass(a);

    return 0;
}
sh-4.2$ main
Hi!
Color is 0x00216948
https://goo.gl/lZkF81

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

Кстати забавно, что 0x216948(16) = 2189640(10). Я сначала подумал что разряды у меня в коде перемешались, потом понял что вместо %x поставил %u.

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

На случай если кто-то будет сейчас кричать по поводу выравнивания в color_t - если влезает в 4 байта - то будет выровнено по 4, даже если мы под x64.

PPP328 ★★★★★
()

Наслаждайся:

int i;
double &d = *reinterpret_cast<double *>(&i);

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

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

Наслаждайся

Всюду извращенцы, смотреть противно, тьфу!

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

полноту по Тьюрингу

Бананы тебе нужнее, чувак.

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

Наслаждайся:

А ведь возьмут и применят...

Неплохо бы к этому прибавить список архитектур, где «d» не вылезет за границы «i», и хотя бы один пример обоснования, где это может делать хоть что-то полезное. Даже обнулить тут нельзя. Ладно бы наоборот с типами...

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

вот как православненько:

type what_is_in is (integer_inside, double_insize);
type t(d : what_is_in) is record
  case d is
    when integer_inside =>
      i : integer;
    when double_inside =>
      d : float;
  end case;
end record;

anonymous
()
27 августа 2017 г.
Ответ на: комментарий от anonymous

то же самое, отображение поправлено.

union a_t[br]
{[br]
int a[10];[br]
char b;[br]
}[br]
#define a a_t.a[br]
#define b a_t.b
сам долго искал, теперь этим пользуюсь

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

Жесть ну тут и движок))) Админы - поправьте пож.(удалите два предыдущих сообщения)

union a_t {
  int a[10];
  char b;
 }
#define a a_t.a
#define b a_t.b

ВОТ!

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.