Hi there,
I was reading the "ex_dir" example but there is something that I can't understand:
if (al_get_fs_entry_mode(entry) & ALLEGRO_FILEMODE_ISDIR)
ALLEGRO_FILEMODE_ISDIR is a simply enum type, since ALLEGRO_FILEMODE_ISDIR is number 5 should contain the number 5.
I don't know how the Boolean operator & works when it's alone, I guess that if some number is bigger than 1 would be true too, but I'm not sure.
But what I can't really understand is that I went to the sources and found this:
typedef enum ALLEGRO_FILE_MODE { ALLEGRO_FILEMODE_READ = 1, ALLEGRO_FILEMODE_WRITE = 1 << 1, ALLEGRO_FILEMODE_EXECUTE = 1 << 2, ALLEGRO_FILEMODE_HIDDEN = 1 << 3, ALLEGRO_FILEMODE_ISFILE = 1 << 4, ALLEGRO_FILEMODE_ISDIR = 1 << 5, } ALLEGRO_FILE_MODE;
What are doing all those << there?, and BTW I don't even know what is the name of that symbol I can't search it in Google. I can't remember if the programming book I have talks about that symbol, besides the typical cout<<.
Thanks!.
The '<<' means shift left, similar to decimal multiplying by ten by moving all the digits leftward relative to the decimal point.
1 << 0 = 1
1 << 1 = 2
1 << 2 = 4
it's easier and neater than
ALLEGRO_FILEMODE_ISFILE = 16
TBH I generally prefer to just use plain hexadecimal notation for this stuff:
typedef enum ALLEGRO_FILE_MODE { ALLEGRO_FILEMODE_READ = 0x1, // 00000001b ALLEGRO_FILEMODE_WRITE = 0x2, // 00000010b ALLEGRO_FILEMODE_EXECUTE = 0x4, // 00000100b ALLEGRO_FILEMODE_HIDDEN = 0x8, // 00001000b ALLEGRO_FILEMODE_ISFILE = 0x10, // 00010000b ALLEGRO_FILEMODE_ISDIR = 0x20 // 00100000b } ALLEGRO_FILE_MODE;
Operator & is a bitwise boolean operator, that is, it applies AND to each pair of bits. It's easy to see if you write the operands in binary. In al_get_fs_entry_mode(entry) & ALLEGRO_FILEMODE_ISDIR, it does this:
XXXXXXXX & 00100000 ------------- 00X00000
The result is all bits to 0, except the 6th least significant bit. If al_get_fs_entry_mode(entry) returns XX1XXXXX (the values of the X's don't matter since you're "anding" X and 0, which is always 0) the result of this operation will be 00100000 too, which evaluates to true. If it's XX0XXXXX the result will be 00000000, which evaluates to false. So effectivelly & is used here to evaluate the n'th bit.
Wow... Thank you Arthur I was able to find more info with the "shift left" words I was already answering you when I read the Oscar post.
But damn Oscar you're a fucking genius, with you and a little bit of cplusplus.com I could understand completely what you're saying.
Since the unique way that & returns 1 is when the operands (the actual bits) are 1, the unique number that it matters (in this case) is the 6th, from right to left, binaries need to be read from right to left?.
Another thing, you surely are using just 8 bits as an example, but in reality they're 32 aren't? something like:
if( 00000000 00000000 00000000 00100000 // <- al_get_fs_entry_mode(entry) &&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&& 00000000 00000000 00000000 00100000) // <- ALLEGRO_FILEMODE_ISDIR
Thank you man, very good explanation. Would you married me?.
Storing flags this way is also useful because you can check multiple values
if (flag & (ALLEGRO_FILEMODE_HIDDEN | ALLEGRO_FILEMODE_ISDIR))