Page 1 of 1
making macros
Posted: Sat Jan 07, 2006 5:52 pm
by GLneo
hello all, ok i'm trying to turn this:
in to a macro:
or
but this makes horrible errors i cant explain, like random undifinded veriables in c files that dont even use these functions!!!, help, thx
Re:making macros
Posted: Sat Jan 07, 2006 6:26 pm
by Rob
How about the C compiler you are using and which version? What do the errors say?
Re:making macros
Posted: Sat Jan 07, 2006 6:34 pm
by GLneo
djgpp, as for errors, when i include the semi-colin every file #includeing syslib.h(where i put the macro) goes crazy ??? ??? ???, but when i dont include the semi-colin i get a few "pause error befor '}' token" right after where i use this macro
Re:making macros
Posted: Sat Jan 07, 2006 6:36 pm
by Simon
Try it this way:
Code: Select all
#define cli() __asm volatile("cli\n")
Then use it like this:
Re:making macros
Posted: Sat Jan 07, 2006 7:05 pm
by GLneo
thx, that worked, but what about more advanced function to macro convertions???:
Code: Select all
inline unsigned char inport(unsigned short port)
{
unsigned char result;
asm volatile("inb %1, %0" : "=a" (result) : "dN" (port));
return result;
}
inline void outport(unsigned short port, unsigned char data)
{
asm volatile("outb %1, %0" : : "dN" (port), "a" (data));
}
inline unsigned short inportw(unsigned short port)
{
unsigned short result;
asm volatile("inw %1, %0" : "=a" (result) : "dN" (port));
return result;
}
inline void outportw(unsigned short port, unsigned short data)
{
asm volatile("outw %1, %0" : : "dN" (port), "a" (data));
}
Re:making macros
Posted: Sun Jan 08, 2006 4:46 am
by Kemp
Well, the single line ones can be done using exactly the same method AFAIK
Re:making macros
Posted: Sun Jan 08, 2006 6:41 am
by Solar
The problem here is that your first cli() is a
function, whereas your second cli() (the macro) is a
statement.
Remember that macros are expanded by the preprocessor, i.e. before the compiler even gets to see the source.
If you define:
and then write
Code: Select all
int main()
{
foo();
cli();
bar();
}
that will get expanded to
Code: Select all
int main()
{
foo();
{ asm("cli"); };
bar();
}
It should be easy to see where the extra brackets and the additional semicolon could lead to troubles, e.g. in an [tt]if[/tt] statement.
A traditional way of encapsuling multi-line blocks in a macro (taking the first of your later examples) is the do-while-block:
Code: Select all
#define cli() do { asm("cli"); } while (0)
That way, the trailing semicolon gets "eaten" by the while-statement.
A macro cannot "return" a value, as it is not a function. With a bit of skill, you can make a macro
evaluate to a certain value, which for all practical purposes is the same. Beware of side-effects, syntactical loopholes and multiple evaluation of parameters, though.
Bottom line, stay away from macros unless you really
must use them.
Re:making macros
Posted: Sun Jan 08, 2006 9:48 am
by GLneo
ok, thx, so i put those functions in the syslib.h file but now every file that include that file and uses those functions gets multiple definition errors, is there a way to inline functions with out errors???, thx
Re:making macros
Posted: Sun Jan 08, 2006 10:24 am
by Kemp
Something to check... have you actually defined things more than once? Check the header files aren't included from more than one place as well.
Re:making macros
Posted: Sun Jan 08, 2006 11:02 am
by Solar
GLneo wrote:
ok, thx, so i put those functions in the syslib.h file but now every file that include that file and uses those functions gets multiple definition errors, is there a way to inline functions with out errors???, thx
Read
GCC manual on "inline" functions.