LINUX.ORG.RU

Вопрос по препроцессору Си


0

0

Часто приходится писать в исходном коде множество обращений к одной и той же структуре. К примеру

if((m->size - m->load) < request_size) { m->mem = realloc(...) }

Можно ли стандартным препроцессором Си сделать некоторый аналог выражения with? Делаю оговорку про "стандартный препроцессор", потому как в ином случае все решается perl'ом и очень просто. Только вот не хочется тащить перл.


А можно поподробнее с with (в перле не силён)? Может тогда и подсказать смогу..

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

> А можно поподробнее с with (в перле не силён)? Может тогда и подсказать смогу..

AFAIU это скорее Паскаль. нечто на вроде:

struct foo {
    int x, y;
};

...
foo f;
with f do {
    x = 10; y = 20;
}
...

ps: синтаксис Сшный поскольку Паскаль как то забыл уже. но смысл надеюсь понятен.

// wbr

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

Ну если так, то похоже сишный препроцессор пролетает :)

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

Да-да, имелось ввиду именно это.

Тогда пока буду писать как писал и паралелльно глядеть на этот sed.

okante
() автор топика

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

#define WITH_START {
#define WITH_END }
#define WITH_ARG(struct,field,fieldtype) fieldtype &field = struct.field;

strict M {
int size;
int load;
void *mem;
} m;

WITH_START
WITH_ARG(m,size,int)
WITH_ARG(m,load,int)
WITH_ARG(m,mem,void*)
if((size - load) < request_size) { mem = realloc(...) }
WITH_END

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

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

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

Проблема была предварительно решена с помщью введения 
дополнительного ключевого слова deafult и написанием 
программы на sed, которая это ключевое слово обрабатывает. 

Предварительно, потому что теститась на совсем небольшом
количестве кода.

----[with.sed]------------------------------------------------
/default/ {h; x; 
		s/^.*\([a-z]\) \* \([a-z][a-z]*\) default.*$/#define pok_sedwith_def \2/; 
		s/^.*\([a-z]\) \([a-z][a-z]*\) default.*$/#define ok_sedwith_def \2/; 
	   x; 
		s/default/\1 /;
	   G;
	}; 
:s
/[^a-z]\./ {x; 
	/^#define p/ {
		x;
		s|\([^a-z]\)\.|\1 pok_sedwith_def->|g;
		bs;
	      }
		x;
		s|\([^a-z]\)\.|\1 ok_sedwith_def.|g;
		bs;
	}
--------------------------------------------------------------

Результат ее работы

------[nalloc.c]----------------------------------------------
#include <stdio.h>

#include "9f.h"

#define MEM_GROW 4096

void * nalloc(struct memory * m default, size_t sz)
{
	if((.mem_size - .mem_load)<sz)
	{
		.mem = realloc(.mem, ((sz / MEM_GROW) +1) * MEM_GROW);
		
	}
	void * res = .mem + .mem_load; 
	.mem_load+=sz;
	return memset(res, 0x00, sz);
}
--------------------------------------------------------------

sed -f with.sed nalloc.c > nalloc.c.seded

------[nalloc.c.seded]----------------------------------------
#include <stdio.h>

#include "9f.h"

#define MEM_GROW 4096

void * nalloc(struct memory * m  , size_t sz)
#define pok_sedwith_def m
{
	if(( pok_sedwith_def->mem_size -  pok_sedwith_def->mem_load)<sz)
	{
		 pok_sedwith_def->mem = realloc( pok_sedwith_def->mem, ((sz / MEM_GROW) +1) * MEM_GROW);
		
	}
	void * res =  pok_sedwith_def->mem +  pok_sedwith_def->mem_load; 
	 pok_sedwith_def->mem_load+=sz;
	return memset(res, 0x00, sz);
} 
--------------------------------------------------------------

Благодарю всех за участие.

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