#define not const?
-
To make my code more readable I'm trying to use a set of defined values in a switch statement. Basically I have a 4 CHAR tag I want to convert to a DWORD.
//#define _makeTag(a,b,c,d) ((#@a << 24) | (#@b << 16) | (#@c << 8) | #@d)
//#define tag_cmap _makeTag(c,m,a,p)
#define _makeTag(x) ((#x[0] << 24) | (#x[1] << 16) | (#x[2] << 8) | #x[3])
#define tag_cmap _makeTag(cmap)In the above I have a 4 CHAR string "cmap" which in DWORD form should be 0x636d6170. However when using in a switch statement the compiler complains that it's not constant. The commented line works, however I believe it to be unreadable. Any suggestions? My previous method was to use a union but that required a loop over all the values, hence slow code.
Waldermort
-
To make my code more readable I'm trying to use a set of defined values in a switch statement. Basically I have a 4 CHAR tag I want to convert to a DWORD.
//#define _makeTag(a,b,c,d) ((#@a << 24) | (#@b << 16) | (#@c << 8) | #@d)
//#define tag_cmap _makeTag(c,m,a,p)
#define _makeTag(x) ((#x[0] << 24) | (#x[1] << 16) | (#x[2] << 8) | #x[3])
#define tag_cmap _makeTag(cmap)In the above I have a 4 CHAR string "cmap" which in DWORD form should be 0x636d6170. However when using in a switch statement the compiler complains that it's not constant. The commented line works, however I believe it to be unreadable. Any suggestions? My previous method was to use a union but that required a loop over all the values, hence slow code.
Waldermort
no, it's not const. Because it's not a compile-time operation. You're accessing a memory location. If you were to look at the generated C-code, it would look like the following:
(("cmap"[0] << 24) | ("cmap"[1] << 16) | ("cmap"[2] << 8) | ("cmap"[3]))
So, it's runtime code, *not* a constant. You could try assigning it to a constant though, as follows:
const tag_cmap = _makeTag(cmap);
instead of the
#define tag_cmap
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams
You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun -
no, it's not const. Because it's not a compile-time operation. You're accessing a memory location. If you were to look at the generated C-code, it would look like the following:
(("cmap"[0] << 24) | ("cmap"[1] << 16) | ("cmap"[2] << 8) | ("cmap"[3]))
So, it's runtime code, *not* a constant. You could try assigning it to a constant though, as follows:
const tag_cmap = _makeTag(cmap);
instead of the
#define tag_cmap
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams
You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braunahmed zahmed wrote:
You're accessing a memory location.
LOL, That thought hit me right after posting the message. Compiler still complains when assigning to a const. I've decided to go with my first method but instead to use
_makeTag('c','m','a','p')
directly in the switch. Thanks again.Waldermort
-
To make my code more readable I'm trying to use a set of defined values in a switch statement. Basically I have a 4 CHAR tag I want to convert to a DWORD.
//#define _makeTag(a,b,c,d) ((#@a << 24) | (#@b << 16) | (#@c << 8) | #@d)
//#define tag_cmap _makeTag(c,m,a,p)
#define _makeTag(x) ((#x[0] << 24) | (#x[1] << 16) | (#x[2] << 8) | #x[3])
#define tag_cmap _makeTag(cmap)In the above I have a 4 CHAR string "cmap" which in DWORD form should be 0x636d6170. However when using in a switch statement the compiler complains that it's not constant. The commented line works, however I believe it to be unreadable. Any suggestions? My previous method was to use a union but that required a loop over all the values, hence slow code.
Waldermort
It turns out that you do not need a macro at all to do what you want. Try this -
DWORD d = 'cmap';
Please note the single quotation marks.
«_Superman_» _I love work. It gives me something to do between weekends.
-
It turns out that you do not need a macro at all to do what you want. Try this -
DWORD d = 'cmap';
Please note the single quotation marks.
«_Superman_» _I love work. It gives me something to do between weekends.
Nice! Out of curiosity what compiler are you using? I think I may have tried that back on VS8 but with errors.
Waldermort
-
Nice! Out of curiosity what compiler are you using? I think I may have tried that back on VS8 but with errors.
Waldermort
I currently use VS2010, but I'm sure this works in older compilers, because this type of assignment is used to tag memory allocations in kernel mode code from ages ago.
«_Superman_» _I love work. It gives me something to do between weekends.
-
To make my code more readable I'm trying to use a set of defined values in a switch statement. Basically I have a 4 CHAR tag I want to convert to a DWORD.
//#define _makeTag(a,b,c,d) ((#@a << 24) | (#@b << 16) | (#@c << 8) | #@d)
//#define tag_cmap _makeTag(c,m,a,p)
#define _makeTag(x) ((#x[0] << 24) | (#x[1] << 16) | (#x[2] << 8) | #x[3])
#define tag_cmap _makeTag(cmap)In the above I have a 4 CHAR string "cmap" which in DWORD form should be 0x636d6170. However when using in a switch statement the compiler complains that it's not constant. The commented line works, however I believe it to be unreadable. Any suggestions? My previous method was to use a union but that required a loop over all the values, hence slow code.
Waldermort
WalderMort wrote:
Any suggestions?
Why, yes: don't use macros, they make your code unreadable ;p No, seriously: using macros is dangerous, with very few exceptions. Regarding your example, your choice of symbol alone already breaks two common safeguards against macro problems: 1. Do not ever use a symbol with starting '_'! This is what the system libraries use internaly to prevent name clashes with any symbols the programmer may define! The problem with name clashes and macros is that macros clash silently, and may break system libraries, resulting in very hard to trace runtime errors (or compiler error,s, if you're lucky) 2. Use capital letters for symbols denoting const or #define symbols. This, also, has to do with preventing name clashes. It may seem overkill, but better be safe than sorry. I've spent many, many weeks hunting down errors caused my macro name clashes caused by other people's code (and in some cases even by MS #defines!). Do yourself (and everyone else) a favor and don't add to that misery!