I have several data structures, each having a field of 4 bytes.
Since 4 bytes equal 1 int
on my platform, I want to use them in case
labels:
switch (* ((int*) &structure->id)) {
case (* ((int*) "sqrt")): printf("its a sqrt!"); break;
case (* ((int*) "log2")): printf("its a log2!"); break;
case (((int) 'A')<<8 + (int) 'B'): printf("works somehow, but unreadable"); break;
default: printf("unknown id");
}
This results in a compile error, telling me the case expression does not reduce to an int
.
How can i use char arrays of limited size, and cast them into numerical types to use in switch
/case
?
You can use char 's for the switch expression and cases as well.
You can't because the switch variable must be an integer or a variable that can be resolved to an integer. It looks like you will need to use a series of ifs. Match the incoming string against an array of strings and just use the array index.
Unlike if-then and if-then-else statements, the switch statement can have a number of possible execution paths. A switch works with the byte , short , char , and int primitive data types.
Follow the exact method employed in video encoding with FourCC codes:
Set a FourCC value in C++
#define FOURCC(a,b,c,d) ( (uint32) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) )
Probably a good idea to use enumerated types or macros for each identifier:
enum {
ID_SQRT = FOURCC( 's', 'q', 'r', 't'),
ID_LOG2 = FOURCC( 'l', 'o', 'g', '2')
};
int structure_id = FOURCC( structure->id[0],
structure->id[1],
structure->id[2],
structure->id[3] );
switch (structure_id) {
case ID_SQRT: ...
case ID_LOG2: ...
}
Disclaimer: Don't use this except for fun or learning purposes. For serious code, use common idioms, never rely on compiler specific behaviour in the general case; if done anyway, incompatible platforms should trigger a compile time error or use the good, general code.
It seems the standard allows multi-character character constants as per the grammar. Haven't checked yet whether the following is really legal though.
~/$ cat main.cc
#include <iostream>
#ifdef I_AM_CERTAIN_THAT_MY_PLATFORM_SUPPORTS_THIS_CRAP
int main () {
const char *foo = "fooo";
switch ((foo[0]<<24) | (foo[1]<<16) | (foo[2]<<8) | (foo[3]<<0)) {
case 'fooo': std::cout << "fooo!\n"; break;
default: std::cout << "bwaah!\n"; break;
};
}
#else
#error oh oh oh
#endif
~/$ g++ -Wall -Wextra main.cc && ./a.out
main.cc:5:10: warning: multi-character character constant
fooo!
edit: Oh look, directly below the grammar excerpt there is 2.13.2 Character Literals, Bullet 1:
[...] An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharac- ter literal has type int and implementation-defined value.
But in the second bullet:
[...] The value of a wide-character literal containing multiple c-chars is implementation-defined.
So be careful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With