Thread: #define w/ function

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    55

    #define w/ function

    Environment:
    Microsoft Visual Studio 2008
    Version 9.0.21022.8 RTM
    Microsoft .NET Framework
    Version 3.5 SP1
    Installed Edition: Professional

    Here is what I have:
    Code:
    #define SPELL_COST(spell, ch)  \
    		switch((spell)) {	\
    			case SPELLID_CLW:	\
    				PLVL((ch));	\
    				break;	\
    		}	\
    	} 
    
    int a = SPELL_COST(SPELLID_CLW, ch);
    I receive these errors upon compilation:
    c:\project\spell_verb_cure_light_wound.cpp(65) : error C2059: syntax error : 'switch'
    c:\project\spell_verb_cure_light_wound.cpp(65) : error C2143: syntax error : missing ';' before '{'
    c:\project\spell_verb_cure_light_wound.cpp(65) : error C2046: illegal case
    c:\project\spell_verb_cure_light_wound.cpp(65) : error C2043: illegal break
    c:\project\spell_verb_cure_light_wound.cpp(159) : error C2059: syntax error : '}'
    c:\project\spell_verb_cure_light_wound.cpp(159) : error C2143: syntax error : missing ';' before '}'
    c:\project\spell_verb_cure_light_wound.cpp(159) : error C2059: syntax error : '}'
    What am I doing wrong?
    Last edited by xwielder; 11-10-2009 at 02:02 PM. Reason: bad info

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    I didnt even know you could that... anyway, I got a similar thing working (or so it "appears" to work). The main differences were
    Code:
    #define SPELL_COST(spell, ch)  \
    		switch((spell)) {	\
    			case SPELLID_CLW:	\
    				PLVL((ch));	\
    				break;	\
    		}	\
    	} 
    
    int a = SPELL_COST(SPELLID_CLW, ch);
    The first red line is a close bracket without a matching open bracket--either add the opening bracket or remove this hanging close bracket (which will work because theres only one statement, I believe). The second red line needs to be inside of a function.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    55
    Yes, then extra hanging bracket was a mistake. I now got rid of that.

    This: int a = SPELL_COST(SPELLID_CLW, ch);

    is called from a different function on a .cpp file. It's not in the same .h file as the define.


    I'm still getting the errors.

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    #define is a simple text substitution; whatever you have in the "body" of your macro is put in place of the macro name. So your code would look something like (removing the extraneous brace):
    Code:
    int a = switch((SPELLID_CLW)) { case SPELLID_CLW: PLVL((ch)); break; }
    While this sort of thing is valid in some languages, like Ruby, it's not in C. The result of a switch statement is not something you can simply assign to a variable. I would recommend a function instead of a macro, but if you have to use a macro, the conditional operator ( ?: ) might be useful.

    If assigning a switch to a variable works on your compiler (as nadroj implies it does for him), that's a compiler extension. I tried it with 5 compilers, and it worked with precisely none, so it doesn't seem to be a common extension if it is one at all.

  5. #5
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Quote Originally Posted by cas
    If assigning a switch to a variable works on your compiler (as nadroj implies it does for him)
    Quote Originally Posted by nadroj
    I got a similar thing working
    Sorry if it was misleading, but by "similar thing" I just meant I was able to modify his #define and use it--not assign its "return" value to something. But what you say seems right, a "switch" doesnt really return anything, and using "?" is definitely a better choice, if what is required is an "if"-"else" type of thing.

    Quote Originally Posted by cas
    I would recommend a function instead of a macro
    Or even an inline function right? I dont use either of these constructs often at all--what is the difference between an inline function and a "function-like" macro?

  6. #6
    Registered User
    Join Date
    Nov 2006
    Posts
    55
    I simply made a small function rather than relying on a #define macro. I had something specific in mind, but for the main purpose the small function will do just fine.

    Thank you all for your input and advice.

  7. #7
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Or even an inline function right? I dont use either of these constructs often at all--what is the difference between an inline function and a "function-like" macro?
    Well, one potential problem is that inline was not standard until C99. This isn't necessarily a large problem because many compilers have provided it as an extension for a long time.

    There are some things a macro can do that a function can't. Some people like to set pointers to NULL after freeing them, and so a wrapper macro can be used:
    Code:
    #define xfree(ptr) do { free(ptr); ptr = NULL; } while(0)
    You can't define a function to do this, because of type issues. You'd need a function for each pointer type, and moreover, it'd have to take a pointer to pointer as the argument so it could actually set the original pointer to NULL.

    For debugging, macros are useful because if you use __FILE__ and __LINE__, they'll be referring to the proper place. As a quick and dirty exapmle:
    Code:
    #include <stdio.h>
    #include <stdarg.h>
    
    #define DBG(fmt, ...) fprintf(stderr, "%s:%d: " fmt, __FILE__, __LINE__, __VA_ARGS__)
    
    static inline void dbg(const char *fmt, ...)
    {
      va_list ap;
    
      va_start(ap, fmt);
      fprintf(stderr, "%s:%d: ", __FILE__, __LINE__);
      vfprintf(stderr, fmt, ap);
    
      va_end(ap);
    }
    
    int main(void)
    {
      DBG("Error %d\n", 1);
      dbg("Error %d\n", 1);
    
      return 0;
    }
    As a C programmer, I've had macros pounded into my head for years. But I've been coming around to inline functions and am using them a lot more now. If it can be done with an inline function, I use an inline function. I reserve macros for what I believe is their rightful place: only when there is no other option. I know they have their uses, but not as many as I used to use them for.

    Functions look a whole lot nicer than multiline macros, anyway.

  8. #8
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Without running that code, is the difference that DBG will print the correct line ( 2nd line of "main" function), whereas dbg will not? Of course (I imagine) they both print the correct file. I imagine your trying to show that theres some difference/limitation, but wasnt positive what it was. Actually, Ill give it a run now...

    And I agree that any (non-trivial) task would look better as a function over a macro.

    EDIT: Neat! Also a cool way to debug (of course opposed to using a debugger). I usually just throw print statements in and see what line is printed, etc. Of course they both achieve the same thing...but your suggestion prevents me from having to think of n different words to type, for the different "debug" statements (because it creates unique "words").
    Last edited by nadroj; 11-10-2009 at 03:21 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. whats wrong here
    By sreetvert83 in forum C++ Programming
    Replies: 15
    Last Post: 09-21-2005, 10:05 AM
  3. DOS, Serial, and Touch Screen
    By jon_nc17 in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 01-08-2003, 04:59 PM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM