Velocity Reviews > C++ > Flags

Flags

Alexis Gatt
Guest
Posts: n/a

 08-25-2005
Hi guys,

I was reading the source code of a lib, and I came across this odd way
of defining flags

#define PHONG_RV (0<<0)
#define PHONG_NH (1<<0)

Here is how they're used:

##### START CODE #####

BRDF *Phong_BRDF::Create_Phonglike(const char *params,
* * * * * * * * * * * * int Phong_Flags=PHONG_PHONG)
{
// some code

* * * * if (strcasecmp(flag1,"rv") == 0)
* * * * * * Phong_Flags |= PHONG_RV;

##### END CODE #####

Many thanks

Alexis

ravinderthakur@gmail.com
Guest
Posts: n/a

 08-25-2005
#define PHONG_RV (0<<0)
#define PHONG_NH (1<<0)

these flags simply evalueate to 0 and 1 respectively. so at every place
that
PHONG_RV and PHONG_NH are used they are replaced by 0 and 1 .

BTW can't understand from where this PHONG_PHONG came from!!!

thanks
rt

Karl Heinz Buchegger
Guest
Posts: n/a

 08-25-2005
Alexis Gatt wrote:
>
> Hi guys,
>
> I was reading the source code of a lib, and I came across this odd way
> of defining flags
>
> #define PHONG_RV (0<<0)
> #define PHONG_NH (1<<0)
>
> Here is how they're used:
>
> ##### START CODE #####
>
> BRDF *Phong_BRDF::Create_Phonglike(const char *params,
> int Phong_Flags=PHONG_PHONG)
> {
> // some code
>
> if (strcasecmp(flag1,"rv") == 0)
> Phong_Flags |= PHONG_RV;
>
> ##### END CODE #####
>
>

<< appplied to integers is know as the 'bitshift left' operator

y << x
The bit pattern of y is shifted left by x bits

number bit pattern << 1 new number
(16 bits assumed)

0 0000000000000000 0000000000000000 0
1 0000000000000001 0000000000000010 2
2 0000000000000010 0000000000000100 4
3 0000000000000011 0000000000000110 6
4 0000000000000100 0000000000001000 8
5 0000000000000101 0000000000001010 10
...

number bit pattern << 2 new number
(16 bits assumed)

0 0000000000000000 0000000000000000 0
1 0000000000000001 0000000000000100 4
2 0000000000000010 0000000000001000 8
3 0000000000000011 0000000000001100 12
4 0000000000000100 0000000000010000 16
5 0000000000000101 0000000000010100 20
...

In the above this is pretty useless, since shifting by 0 bits
doesn't alter the number. In fact, IIRC, it has undefined behaviour
(are you sure it didn't read
#define PHONG_RV (1<<0)
#define PHONG_NH (1<<1)

that would make far more sense)

--
Karl Heinz Buchegger
http://www.velocityreviews.com/forums/(E-Mail Removed)

Alexis Gatt
Guest
Posts: n/a

 08-25-2005

On 2005-08-25 13:01:30 +0100, Karl Heinz Buchegger <(E-Mail Removed)> said:
> << appplied to integers is know as the 'bitshift left' operator

I know that. i just dont understand why someone would define flags in
this way rather than the good old "#define MY_FLAG 0x00001"

> (are you sure it didn't read
> #define PHONG_RV (1<<0)
> #define PHONG_NH (1<<1)
>
> that would make far more sense)

The whole list of flags is actually

#define PHONG_RV (0<<0)
#define PHONG_NH (1<<0)
#define PHONG_ORIG (0<<1)
#define PHONG_NEW (1<<1)
#define PHONG_PHONG (0<<2)
#define PHONG_SCHLICK (1<<2)

Karl Heinz Buchegger
Guest
Posts: n/a

 08-25-2005
Alexis Gatt wrote:
>
>
> On 2005-08-25 13:01:30 +0100, Karl Heinz Buchegger <(E-Mail Removed)> said:
> > << appplied to integers is know as the 'bitshift left' operator

>
> I know that. i just dont understand why someone would define flags in
> this way rather than the good old "#define MY_FLAG 0x00001"

So why then are you asking:

>
> > (are you sure it didn't read
> > #define PHONG_RV (1<<0)
> > #define PHONG_NH (1<<1)
> >
> > that would make far more sense)

>
> The whole list of flags is actually
>
> #define PHONG_RV (0<<0)
> #define PHONG_NH (1<<0)
> #define PHONG_ORIG (0<<1)
> #define PHONG_NEW (1<<1)
> #define PHONG_PHONG (0<<2)
> #define PHONG_SCHLICK (1<<2)

The idea behind all this seems to be:

The value PHONG_RV is enocded, if bit 0 has the value 0, hence 0 << 0
The value PHONG_NH is encoded, if bit 0 has the value 1, hence 1 << 0
The value PHONG_ORIG is encoded, if bit 1 has the value 0, hence 0 << 1
PHONG_NEW 1 1 1 << 1
PHONG_PHONG 2 0 0 << 2
PHONG_SCHLICK 2 1 1 << 2

thus the individual values can simply be order together to get the
correct result.

Well. It is a great idea for documentation. But then, not that usefull for
actual programming. I would not introduce 2 macros for the same bit and name
them differently but instead just have one. Much less confusion in the long run.
Especially because the 0-coding macros cannot easily be used for generating masks.
If you want to test if a flags variable contains the value PHONG_ORIG, there is no way
to express that using PHONG_ORIG. Instead one has to use PHONG_NEW and must have the
knowledge that PHONG_ORIG is the conceptual complement of PHONG_NEW.

if( (Flags & PHONG_ORIG) == PHONG_ORIG )

one has to write
if( ( Flags & PHONG_NEW ) != PHONG_NEW )
or
if( !(Flags & PHONG_NEW ) )

to express that idea.

--
Karl Heinz Buchegger
(E-Mail Removed)

Chris Theis
Guest
Posts: n/a

 08-25-2005

"Karl Heinz Buchegger" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
[SNIP]
> Well. It is a great idea for documentation. But then, not that usefull for
> actual programming. I would not introduce 2 macros for the same bit and
> name
> them differently but instead just have one. Much less confusion in the
> long run.
> Especially because the 0-coding macros cannot easily be used for
> If you want to test if a flags variable contains the value PHONG_ORIG,
> there is no way
> to express that using PHONG_ORIG. Instead one has to use PHONG_NEW and
> must have the
> knowledge that PHONG_ORIG is the conceptual complement of PHONG_NEW.
>
> if( (Flags & PHONG_ORIG) == PHONG_ORIG )
>
> one has to write
> if( ( Flags & PHONG_NEW ) != PHONG_NEW )
> or
> if( !(Flags & PHONG_NEW ) )
>
> to express that idea.

Yikes, somehow that idea/concept scares me

Chris

Greg
Guest
Posts: n/a

 08-25-2005

Alexis Gatt wrote:
> Hi guys,
>
> I was reading the source code of a lib, and I came across this odd way
> of defining flags
>
> #define PHONG_RV (0<<0)
> #define PHONG_NH (1<<0)
>
> Here is how they're used:
>
> ##### START CODE #####
>
> BRDF *Phong_BRDF::Create_Phonglike(const char *params,
> int Phong_Flags=PHONG_PHONG)
> {
> // some code
>
> if (strcasecmp(flag1,"rv") == 0)
> Phong_Flags |= PHONG_RV;
>
> ##### END CODE #####
>
>
>
> Many thanks
>
> Alexis

The code doesn't work very well. Using a zero to store a distinct value
is error-prone to say the least. In fact I would have expected the

Phong_Flags |= PHONG_RV;

since it has no side effects (in other words, it does nothing). And if
theprogrammer is going to use macros, at least make them function
macros:

#define PHONG_RV(a) (!(0x01 & a))

After all, you don't have a PHONG_RV unless you a set of flags. Of
course the C++, more typesafe version would be an inline function:

inline bool PHONG_RV(unsigned int inFlags)
{
return not (0x01 bitand inFlags);
}

Greg

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post Steve Holden Python 0 02-08-2009 04:09 PM Echy Firefox 0 12-27-2004 11:35 PM Gunit VHDL 2 06-28-2004 03:33 PM DG Perl 0 05-27-2004 08:37 PM Valentin Tihomirov VHDL 5 11-11-2003 05:16 PM