I'm porting some of my code from masm to c++. (I use MSVC++6)
How can I write a macro in C?


Sort MACRO column:REQ
for(i = 0; i < ItemCount-1; i++)
{
min = i;
for(j = i+1; j <= ItemCount-1; j++)
if(lstrcmp(pAnalisiVal->column, pAnalisiVal->column) > 0) min = j;

Exchange(i, min);
}
ENDM


This is the code in C mixed asm and I have to make "column" as a parameter.
Posted on 2004-09-10 07:21:47 by greenant
The pre-processor in C is much less powerful than the macros in MASM, but it makes up for it with a much better compiler!

Just write it as a separate function, and specifiy "inline". The compiler will then decide whether it's worth inlining, and optimise around it when it does.

Mirno
Posted on 2004-09-10 08:59:30 by Mirno
or if you really really really (really!) want something like a macro, you can use #define to do so. it will result in unreadable code though.
Posted on 2004-09-10 10:43:26 by lifewire
#define does not cope with variables local to the macro, so if you declare an "int i;" in the macro, it may conflict with a variable outside the scope of the macro.

The C macro language is really by all accounts very poor, but like I said, the compiler is way more clever (at least modern optimising compilers).

#defines really suck, and should only be used where absolutely necessary. They make the code look ugly too (oh how I hate the "old skool" C coders who use #if 0 to comment blocks of code out....)!

Mirno
Posted on 2004-09-10 11:49:45 by Mirno
it is ugly, indeed, that is why i recommend it only if you really want it :)

about locals:

#define SWAP_INT(a,b) { int c=a; a=b; b=c; }

a really stupid example, but it uses a local without problems, doesn't it?
Posted on 2004-09-10 12:29:21 by lifewire
I can't use a function because "column" is the name of a member of the structure. I could pass the offset of the member, but it is not so easy as asm macro
Posted on 2004-09-10 12:40:09 by greenant
I suppose you want something like this:


extern int lstrcmp(const char *s1, const char *s2);
extern void Exchange(int a, int b);

void foo(void)
{
int i;
int j;
int min;
int ItemCount = 123;
struct {
char *a;
char *b;
} **pAnalisiVal;

#define MY_SORT_MACRO(column) \
for (i = 0; i < ItemCount - 1; i++) { \
min = i; \
for (j = i + 1; j <= ItemCount - 1; j++) \
if (lstrcmp(pAnalisiVal[j]->column, pAnalisiVal[min]->column) > 0) \
min = j; \
Exchange(i, min); \
}

MY_SORT_MACRO(a);
MY_SORT_MACRO(b);

#undef MY_SORT_MACRO

}

I strongly suggest using a function instead. You can get the offset of the member using the offsetof() macro, and pass it to your comparison function. You could use qsort() or std::sort() instead.
Posted on 2004-09-10 14:18:52 by death
I created a VirtualListView in c++ with Selection Sort as sort method.
Then I converted this code to asm and I changed Selection Sort with MergeSort because it is faster.
I need a stable algorithm so I cant use qsort function because it is not stable.
Now I want to change the c++ code: Selection Sort with Merge Sort

This is the asm macro


SelSortUp MACRO column:REQ
LOCAL _h_loop, _i_loop, _j_loop, _eo_j_loop
;int 3
;edi = h
;ebx = a = pGameStr
;i = ivar
;j = jvar
;esi = v

_h_loop:

mov ivar, edi

_i_loop:
mov eax, ivar
mov jvar, eax
mov esi, [ebx + eax*4]

_j_loop:
cmp jvar, edi
jl _eo_j_loop

mov eax, jvar
sub eax, edi
mov eax, [ebx + eax*4]
invoke lstrcmp, addr [esi.GAME_STR].column, addr [eax.GAME_STR].column

cmp al, 0
jnl _eo_j_loop

mov edx, jvar
mov ecx, edx
sub edx, edi

mov eax, [ebx + edx*4]
mov [ebx + ecx*4], eax

sub jvar, edi

jmp _j_loop

_eo_j_loop:
mov eax, jvar
mov [ebx + eax*4], esi

inc ivar
mov eax, ItemCount
dec eax
cmp ivar, eax
jle _i_loop


xor edx, edx
mov eax, edi
mov edi, 3
div edi
mov edi, eax
or eax, eax
jnz _h_loop

ENDM


This is the sort function


test SortOrder, 1
.if ZERO?
.if eax == LV_ROMNAME
SelSortUp RomName

.elseif eax == LV_DESCRIPT
SelSortUp Descript

...................
.endif
.else
.if eax == LV_ROMNAME
SelSortDown RomName

.elseif eax == LV_DESCRIPT
SelSortDown Descript

...............
.endif
.endif


AnalisiVal struct


struct AnalisiVal
{
//Id univoco dell'analisi
unsigned long ID;

//Informazioni sul prodotto
unsigned long tipo;
long origine;
unsigned long data;
unsigned long prog;
unsigned long lav;

//Caratteristiche fisiche
float secco;
float ph;
unsigned long visco;

//Reatt
unsigned long r30;
unsigned long r70;
unsigned long r80;
unsigned long r100;

//Note
char note[248];

long conforme;
};
Posted on 2004-09-12 03:05:37 by greenant
You can use std::stable_sort().
Posted on 2004-09-12 06:11:48 by death
I don't want to use a c++ function. I don't use STL, only Windows Api
Posted on 2004-09-12 06:13:31 by greenant