Advertisement

Macro(???????????)

Started by November 16, 2001 10:11 PM
15 comments, last by Sinner_Zero 22 years, 11 months ago
Ok, ok, ok. Can someone explain macros to me, I use them and all but what exacly are the specifics on them? possibly a tutorial link if it''s so complicated. Any help is greatly appreciated.
A macro is a symbol whose definition is substituted everywhere it occurs before compilation. The compilation process for a C/C++ source file includes a stage called "preprocessing." It is the preprocessor that handles all those keywords that begin with the hash symbol (#). #include, for example, causes the preprocessor to place the entire included file in place. #define causes an environment symbol to be created (and its value to be substituted everywhere it is referenced in code), which is the basis of macros. Here''s an example:
#define deg2rad(x) (M_PI/180 * x) 

Now everywhere in the same file (or files that include this file) where the program sees deg2rad(v) - where v is any value - the preprocessor will substitute (M_PI/180 * v) in its place (note that M_PI is also a "macro" of sorts; it''s a defined symbol). Now if v was a non-numeric value like a string
int y = deg2rad("a"); 

the compiler will puke where it''s trying to multiply numbers and a string. Unfortunately, that would be the line where the macro was defined, so tracking down the bug would be pretty hard. You see, macros don''t do type-checking, so you can get some very bizarre behavior (which will sometimes compile but crash hard during execution).

If you''re using C++, use inline functions instead (and use const for constant values):
#ifndef M_PI // some platforms define M_PIconst float M_PI = 3.1459;#endifinline float deg2rad(float f) { return (180 / M_PI) * f; } 

The problem with this as opposed to macros is that if you pass it an integer, you''ll get a type mismatch. However, since you''re using C++ you might as well make it a template function:
inline template <typename T> T deg2rad(T val) { return (180 / M_PI) * val; } 


In conclusion, if you''re a C++ programmer, stick to inlines and const values; they were designer specifically to combat the shortcomings of macros and defines.
Advertisement
I am C++ guy, but you see all these people demand C instead, so I haveto get used to doing all of this C stuff, hell my whole Win32 book is C and freakin' UNICODE compliance, damn code nazis.

Ok, um, thnx a ton for the explanation, but I got one more thingy thats sorta bothering.

#define __T(x) L##x    

Makes a call to __T("Hello!") into a call to L"Hello!" is what this book says. Ummm... does this make sense to you? is this L## thing what I think it is. In which case can I then do like

#define MYCRAZYCRAP##x __T(x)    

that way I can do MYCRAZYCRAP"Hello!" which would actually do __T("Hello!") which would actually do L"Hello!"

If thats not the way to define such a thing is there a way?

And can anyone tell me if the Bjorne guys C++ reference would cover all of this, I mean it would right? Cuz I'm thinking of buying that and with it the STL book that amazon recommends. Anyone?

Edited by - Sinner_Zero on November 17, 2001 8:40:39 PM
The ## preprocessor directive is used to concatenate the tokens before and after it. It's not very useful under most circumstances. Here's an example of how it works:
    #define concat(a, b) a##bint main() {    int xy = 10;    cout << conat(x,y);}  

The preprocessor transforms
cout << concat(x,y);
int
cout << xy;
which prints 10.

-Neophyte

EDIT: Formatting
- Death awaits you all with nasty, big, pointy teeth. -

Edited by - Neophyte on November 17, 2001 8:45:12 PM
So is there anyway for me to recreate something like

char a[] = L"Hello!";

?
Try this (I''m not sure if it works, I haven''t had to use Unicode yet).
  wchar_t a[] = L"Hello!";  

The "wchar_t" is the standard wide character variable. I''m not sure if the "L" prefix is standard and I''m not sure if they get along together, so...

[Resist Windows XP''s Invasive Production Activation Technology!]
Advertisement
Bjarne Stroustrup''s book "The C++ Programming Language" cover''s a lot technical, but it doesn''t go much into depth with C technicalities (like how to do asm in C and such), and neither does it go into depth with STL technicalities, i''d recommend for pure C getting Kernighan and Richie''s "The C Programming Language" and P.J. Plauger''s "The C++ Standard Template Library"
There is little about macros in the Stroustrup (3rd ed).
I''d advise you to buy also Herbert Schildt "C/C++ Programmer''s Reference (2nd ed)", published by Osborne.

As for ##, it indeed does token concatenation :

  #define CAT( X, Y ) X##YCAT( 2, 3 ) is 23CAT( A, 5 ) is A5  


But, IMHO, more interesting is # which can be very useful to print debugging statements :

  #define STR( X ) #XSTR( x ) is "x"#define DBG( X ) X; //     { if( debug_mode ) std::cerr << #X << std::endl; }  
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
quote: Original post by abdulla
Bjarne Stroustrup''s book "The C++ Programming Language" cover''s a lot technical, but it doesn''t go much into depth with C technicalities (like how to do asm in C and such)...

Assembly language is not a standard part of C or C++, it is an extension added by the compiler. That''s probably why he doesn''t cover it .

[Resist Windows XP''s Invasive Production Activation Technology!]
fruny, I didnt get that IMHO part, wtf are you doing there, can you please explain?

This topic is closed to new replies.

Advertisement