开发者

Macro definition in C and C++

开发者 https://www.devze.com 2023-04-12 16:30 出处:网络
I am a new programmer in C/C++ having programmed in Java for quite a while. I am currently understanding some C开发者_运维知识库 code. Here I am seeing some macro definitions like:

I am a new programmer in C/C++ having programmed in Java for quite a while. I am currently understanding some C开发者_运维知识库 code. Here I am seeing some macro definitions like:

/* Flags for ds_flags */ 
#define DSF_OVER        (1<<0)  
#define DSF_DISPLAY     (1<<1)    
#define DSF_CALLFLOW    (1<<2) 

I am not able to understand why do we have to define these macros in such a manner. What is the advantage gained in these rather than in defining like:

#define DSF_OVER        0
#define DSF_DISPLAY     1    
#define DSF_CALLFLOW    2


When seeing something like

#define DSF_FOO 0x800
#define DSF_BAR 2048

not many people are able to quickly see that only one bit is set, and which it is.

#define DSF_FOO (1<<11)

however makes this very clear.


The only potential advantage is that it's easier to see that the code correctly defines each constant with one distinct bit set.

Most people will see that at a glance anyway if you just write 1, 2, 4 instead of 1<<0, 1<<1, 1<<2, so perhaps it's difficult to see that advantage in this example. Once you get to 1<<15, some people would miss a typo like 32748.


These are bit values, e.g. 1, 2, 4. 8.

Bit 0 = (1 << 0) = 1
Bit 1 = (1 << 1) = 2
Bit 2 = (1 << 2) = 4
Bit 3 = (1 << 3) = 8
...etc...

It's a more convenient and robust way of defining them than using explicit values, especially as the bit indices get larger (e.g. (1<<15) is much easier to understand and more intuitive than 32768 or 0x8000, in that it obviously means "bit 15" rather than some possibly arbitrary number).


Using (1<<x) in a define makes it clear that the value is a single bit and not a number.

For the compiler it makes no difference because (1<<2) is computed at compile time and not at runtime. Showing clearly that they are single-bit values is instead useful for whoever reads the code because for example they could be multiple values that can be combined or that a single variable can be used to store multiple flags:

// Multiple options are combined with bitwise-or
show_message(DSF_CAPTION|DSF_ALERT, "Hey...");
...

// Checking is made using bitwise-and, not equality
if (status & DSF_RUNNING)
  ...

Also requiring specific bits is sometimes needed when dealing with hardware (e.g. on a certain I/O port may be you need to specify the fifth bit because that's how the hardware is wired, and (1<<4) is more readable than 16 for that).


It's for clarity really - it shows that the different definitions are bit masks that will typically be used together to filter values from an input. I don't know if you already know what a bit mask is - here's a link: http://www.vipan.com/htdocs/bitwisehelp.html


Some times the position of the bits represent some bit operations like in your case:

#define DSF_OVER        (1<<0)  is 1
#define DSF_DISPLAY     (1<<1)  is 2  
#define DSF_CALLFLOW    (1<<2)  is 4 (This is not 3)

If you were to add a new item later, you will do it as

#define DSF_OVER       1
#define DSF_DISPLAY    2  
#define DSF_CALLFLOW   4
#define DSF_CALLNEW    5.

You cant have a value 5 here since it is two bits enabled (101 in binary). To avoid such potential errors it is always safe to use macros using >>. It can't produce a value of 5 (101) by error in when the next bit should be 1000 in binary.

It is all about programming convenience to produce error free code.


Regardless of whether you prefer (1 << n) or not, everyone should be aware of what hexadecimal numbers signify. Whenever you encounter hex in source code it always means that som bit- or byte manipulations are taking place. You don't use hex notation for any other purpose. Therefore it is wise to write masks, numeric bit manipulation literals etc as hex.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号