Flags

Discussion in 'C++' started by Alexis Gatt, Aug 25, 2005.

  1. Alexis Gatt

    Alexis Gatt Guest

    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 #####


    Could someone please explain me how they work please?

    Many thanks

    Alexis
    Alexis Gatt, Aug 25, 2005
    #1
    1. Advertising

  2. Alexis Gatt

    Guest

    #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
    , Aug 25, 2005
    #2
    1. Advertising

  3. 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 #####
    >
    > Could someone please explain me how they work please?
    >


    << 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
    Karl Heinz Buchegger, Aug 25, 2005
    #3
  4. Alexis Gatt

    Alexis Gatt Guest

    Thanks for the answer.

    On 2005-08-25 13:01:30 +0100, Karl Heinz Buchegger <> 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)
    Alexis Gatt, Aug 25, 2005
    #4
  5. Alexis Gatt wrote:
    >
    > Thanks for the answer.
    >
    > On 2005-08-25 13:01:30 +0100, Karl Heinz Buchegger <> 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:
    > Could someone please explain me how they work please?



    >
    > > (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.

    so instead of
    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
    Karl Heinz Buchegger, Aug 25, 2005
    #5
  6. Alexis Gatt

    Chris Theis Guest

    "Karl Heinz Buchegger" <> wrote in message
    news:...
    [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
    > 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.
    >
    > so instead of
    > 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
    Chris Theis, Aug 25, 2005
    #6
  7. Alexis Gatt

    Greg Guest

    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 #####
    >
    >
    > Could someone please explain me how they work please?
    >
    > 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
    compiler to warn about this line:

    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
    Greg, Aug 25, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Valentin Tihomirov

    flags vs. comparator

    Valentin Tihomirov, Nov 10, 2003, in forum: VHDL
    Replies:
    5
    Views:
    612
    Valentin Tihomirov
    Nov 11, 2003
  2. Gunit
    Replies:
    2
    Views:
    543
    Just an Illusion
    Jun 28, 2004
  3. DG
    Replies:
    0
    Views:
    444
  4. Jan Nielsen

    AD user flags

    Jan Nielsen, Apr 5, 2004, in forum: ASP .Net
    Replies:
    6
    Views:
    3,813
    Jeffrey Tan[MSFT]
    Apr 13, 2004
  5. Steve Holden
    Replies:
    0
    Views:
    760
    Steve Holden
    Feb 8, 2009
Loading...

Share This Page