making macros

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
GLneo

making macros

Post by GLneo »

hello all, ok i'm trying to turn this:

Code: Select all

void cli()
{
    asm("cli");
}
in to a macro:

Code: Select all

#define cli() { asm("cli"); }
or

Code: Select all

#define cli() { asm("cli") }
but this makes horrible errors i cant explain, like random undifinded veriables in c files that dont even use these functions!!!, help, thx
Rob

Re:making macros

Post by Rob »

How about the C compiler you are using and which version? What do the errors say?
GLneo

Re:making macros

Post 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
Simon

Re:making macros

Post by Simon »

Try it this way:

Code: Select all

#define cli() __asm volatile("cli\n")
Then use it like this:

Code: Select all

cli();
GLneo

Re:making macros

Post 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));
}
Kemp

Re:making macros

Post by Kemp »

Well, the single line ones can be done using exactly the same method AFAIK
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:making macros

Post 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:

Code: Select all

#define cli() { asm("cli") }
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.
Every good solution is obvious once you've found it.
GLneo

Re:making macros

Post 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
Kemp

Re:making macros

Post 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.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:making macros

Post 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.
Every good solution is obvious once you've found it.
Post Reply