asking for an opinion from the collective wisdom here

Discussion in 'C++' started by Devon Null, Jun 2, 2007.

  1. Devon Null

    Devon Null Guest

    I was simply wondering if this was a mal-formed class header:

    #ifndef _items_h_
    #define _items_h_

    #include <iostream>
    #include <string>
    #include <vector>

    using namespace std;

    class Item
    {
    public:
    Item( float weight = 0, bool set_can_equip = false, bool
    set_can_attack = false, bool set_can_defend = false, bool set_can_drink
    = false, bool set_can_eat = false, bool set_can_use = false, bool
    set_is_consumable = false, bool set_is_magical = false );
    //Below are the set and get functions for all variables in this
    class
    void set_weight( float weight ) { item_weight = weight; }
    float get_weight() { return item_weight; }

    void set_can_equip( bool set_can_equip ) { can_equip =
    set_can_equip; }
    bool get_can_equip() { return can_equip; }

    void set_can_attack( bool set_can_attack ) { can_attack =
    set_can_attack; }
    bool get_can_attack() { return can_attack; }

    void set_can_defend( bool set_can_defend ) { can_defend =
    set_can_defend; }
    bool get_can_defend() { return can_defend; }

    void set_can_drink( bool set_can_drink ) { can_drink =
    set_can_drink; }
    bool get_can_drink() { return can_drink; }

    void set_can_eat( bool set_can_eat ) { can_eat = set_can_eat; }
    bool get_can_eat() { return can_eat; }

    void set_can_use( bool set_can_use ) { can_use = set_can_use; }
    bool get_can_use() { return can_use; }

    void set_is_consumable( bool set_is_consumable ) { is_consumable
    = set_is_consumable; }
    bool get_is_consumable() { return is_consumable; }

    void set_is_magical( bool set_is_magical ) { is_magical =
    set_is_magical; }
    bool get_is_magical() { return is_magical; }

    void describe(); // simply returns description (see below)
    void clear_describe(); // clears description
    void add_describe( string line_to_add );
    /*Line above checks to see if description is set to either
    need_set or desc_cleared, and if so description.clear()
    then push_back( line_to_add ), else just push_back( line_to_add)*/

    private: // These are stats that will be set for every item created
    string need_set; // description is initialized with this
    string desc_cleared; // description will be set to this after it
    has been cleared
    vector<string> description; // This is to allow multi-line
    descriptions
    float item_weight; // These are pretty self explanatory I think
    bool can_equip;
    bool can_attack;
    bool can_defend;
    bool can_drink;
    bool can_eat;
    bool can_use;
    bool is_consumable;
    bool is_magical;
    };

    #endif

    but as I read along I was confused over something. The above works just
    fine, but I was also wondering should the constructor be this:

    Item( float weight = 0, bool set_can_equip = false, bool set_can_attack
    = false, bool set_can_defend = false, bool set_can_drink = false, bool
    set_can_eat = false, bool set_can_use = false, bool set_is_consumable =
    false, bool set_is_magical = false );

    with a constructor body like this in the cpp file:

    Item::Item( float weight, bool set_can_equip, bool set_can_attack, bool
    set_can_defend, bool set_can_drink, bool set_can_eat, bool set_can_use )
    {
    item_weight = weight;
    can_equip = set_can_equip;
    can_attack = set_can_attack;
    can_defend = set_can_defend;
    can_drink = set_can_drink;
    can_eat = set_can_eat;
    can_use = set_can_use;
    is_consumable = set_is_consumable;
    is_magical = set_is_magical;
    need_set = "You need to set a description here!\n";
    desc_cleared = "The description has been cleared.\n";
    description.clear();
    description.push_back( need_set );
    }

    or this:

    Item() : float weight( 0 ), bool can_equip( false ), bool can_attack(
    false ), bool can_defend( false ), bool can_drink( false ), bool
    can_eat( false ), bool can_use( false ), bool is_consumable( false ),
    bool is_magical( false );

    and lose the entire body of the constructor in the cpp file? I will need
    to pass in parameters to override the defaults when I instantiate the
    objects.

    Question 1: Is this a mal-formed class header?
    Question 2: Which should I use for the initialization list?

    Thanks in advance.
    DN
    --
    [there are no x's in my email]

    I have the right to remain silent
    (and should probably use it as much as possible)
    Anything I type can and will be used against me
    in a court of idiocy
    I have the right to be wrong
    (and probably am)
    If I can not furnish my own wrongness
    I'm sure someone will provide it for me.
    Devon Null, Jun 2, 2007
    #1
    1. Advertising

  2. Devon Null

    red floyd Guest

    Devon Null wrote:
    > I was simply wondering if this was a mal-formed class header:
    >
    > #ifndef _items_h_
    > #define _items_h_


    Yes, you are malformed right here. Per the Standard, any identifier
    with a leading underscore is reserved to the implementation in the
    global namespace. _items_h_ is in the global namespace.
    red floyd, Jun 2, 2007
    #2
    1. Advertising

  3. Devon Null

    Daniel T. Guest

    Devon Null <> wrote:

    > I was wondering should the constructor be this:
    >
    > Item( float weight = 0, bool set_can_equip = false, bool set_can_attack
    > = false, bool set_can_defend = false, bool set_can_drink = false, bool
    > set_can_eat = false, bool set_can_use = false, bool set_is_consumable =
    > false, bool set_is_magical = false );
    >
    > with a constructor body like this in the cpp file:
    >
    > Item::Item( float weight, bool set_can_equip, bool set_can_attack, bool
    > set_can_defend, bool set_can_drink, bool set_can_eat, bool set_can_use )
    > {
    > item_weight = weight;
    > can_equip = set_can_equip;
    > can_attack = set_can_attack;
    > can_defend = set_can_defend;
    > can_drink = set_can_drink;
    > can_eat = set_can_eat;
    > can_use = set_can_use;
    > is_consumable = set_is_consumable;
    > is_magical = set_is_magical;
    > need_set = "You need to set a description here!\n";
    > desc_cleared = "The description has been cleared.\n";
    > description.clear();
    > description.push_back( need_set );
    > }
    >
    > or this:
    >
    > Item() : float weight( 0 ), bool can_equip( false ), bool can_attack(
    > false ), bool can_defend( false ), bool can_drink( false ), bool
    > can_eat( false ), bool can_use( false ), bool is_consumable( false ),
    > bool is_magical( false );
    >
    > and lose the entire body of the constructor in the cpp file? I will need
    > to pass in parameters to override the defaults when I instantiate the
    > objects.


    You can't lose the entire body of the constructor. However to answer the
    underlying question, you should use the no argument constructor and just
    initialize all the variables.

    Item::Item() :
    weight( 0 ),
    can_equip( false ),
    can_attack( false ),
    can_defend( false ),
    can_drink( false ),
    can_eat( false ),
    can_use( false ),
    is_consumable( false ),
    is_magical( false )
    { }

    At some point you will realize that your code is full of blocks that
    check the various flags in this class and behave differently depending
    on the setting of the flag. Then when you learn about polymorphism, you
    will start writing better classes.
    Daniel T., Jun 2, 2007
    #3
  4. Devon Null

    terminator Guest

    On Jun 3, 1:06 am, "Daniel T." <> wrote:
    > Devon Null <> wrote:
    > > I was wondering should the constructor be this:

    >
    > > Item( float weight = 0, bool set_can_equip = false, bool set_can_attack
    > > = false, bool set_can_defend = false, bool set_can_drink = false, bool
    > > set_can_eat = false, bool set_can_use = false, bool set_is_consumable =
    > > false, bool set_is_magical = false );

    >
    > > with a constructor body like this in the cpp file:

    >
    > > Item::Item( float weight, bool set_can_equip, bool set_can_attack, bool
    > > set_can_defend, bool set_can_drink, bool set_can_eat, bool set_can_use )
    > > {
    > > item_weight = weight;
    > > can_equip = set_can_equip;
    > > can_attack = set_can_attack;
    > > can_defend = set_can_defend;
    > > can_drink = set_can_drink;
    > > can_eat = set_can_eat;
    > > can_use = set_can_use;
    > > is_consumable = set_is_consumable;
    > > is_magical = set_is_magical;
    > > need_set = "You need to set a description here!\n";
    > > desc_cleared = "The description has been cleared.\n";
    > > description.clear();
    > > description.push_back( need_set );
    > > }

    >
    > > or this:

    >
    > > Item() : float weight( 0 ), bool can_equip( false ), bool can_attack(
    > > false ), bool can_defend( false ), bool can_drink( false ), bool
    > > can_eat( false ), bool can_use( false ), bool is_consumable( false ),
    > > bool is_magical( false );

    >
    > > and lose the entire body of the constructor in the cpp file? I will need
    > > to pass in parameters to override the defaults when I instantiate the
    > > objects.

    >
    > You can't lose the entire body of the constructor. However to answer the
    > underlying question, you should use the no argument constructor and just
    > initialize all the variables.
    >
    > Item::Item() :
    > weight( 0 ),
    > can_equip( false ),
    > can_attack( false ),
    > can_defend( false ),
    > can_drink( false ),
    > can_eat( false ),
    > can_use( false ),
    > is_consumable( false ),
    > is_magical( false )
    > { }
    >
    > At some point you will realize that your code is full of blocks that
    > check the various flags in this class and behave differently depending
    > on the setting of the flag. Then when you learn about polymorphism, you
    > will start writing better classes.- Hide quoted text -
    >
    > - Show quoted text -


    both forms can be used for ctors but the later is better when const
    data members exist and the former is needed when members have to be
    assigned assciated values:

    int f(int,int);//A big function

    class A{
    public:
    const int m;
    int n,p;
    A(int i,int j):
    p(0),
    m(f(i,j))//const must be initialized here.
    {n=m;};/*if n is initailized in the initializer list f is called
    twice which time expensive.*/
    };
    terminator, Jun 2, 2007
    #4
  5. Devon Null

    terminator Guest

    On Jun 2, 11:51 pm, red floyd <> wrote:
    > Devon Null wrote:
    > > I was simply wondering if this was a mal-formed class header:

    >
    > > #ifndef _items_h_
    > > #define _items_h_

    >
    > Yes, you are malformed right here. Per the Standard, any identifier
    > with a leading underscore is reserved to the implementation in the
    > global namespace. _items_h_ is in the global namespace.


    what is wrong with it?
    This is an avanced technique used in proffesional libraries to prevent
    probable linker errors generated by repetition.It also decreases
    compile time.

    regards,
    FM
    terminator, Jun 2, 2007
    #5
  6. Devon Null

    Jerry Coffin Guest

    In article <>,
    says...
    > On Jun 2, 11:51 pm, red floyd <> wrote:
    > > Devon Null wrote:
    > > > I was simply wondering if this was a mal-formed class header:

    > >
    > > > #ifndef _items_h_
    > > > #define _items_h_

    > >
    > > Yes, you are malformed right here. Per the Standard, any identifier
    > > with a leading underscore is reserved to the implementation in the
    > > global namespace. _items_h_ is in the global namespace.

    >
    > what is wrong with it?
    > This is an avanced technique used in proffesional libraries to prevent
    > probable linker errors generated by repetition.It also decreases
    > compile time.


    As he already pointed out, what's wrong is the _name_ you've used. The
    technique is perfectly legitimate and allowable, but the name you've
    used is not. If you change to something like:

    #ifndef ITEMS_H_INCLUDED
    #define ITEMS_H_INLCUDED

    you'll be fine, because this name does NOT have a leading underscore
    like the one you used.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, Jun 3, 2007
    #6
  7. terminator wrote:
    > On Jun 2, 11:51 pm, red floyd <> wrote:
    >> Devon Null wrote:
    >>> I was simply wondering if this was a mal-formed class header:
    >>> #ifndef _items_h_
    >>> #define _items_h_

    >> Yes, you are malformed right here. Per the Standard, any identifier
    >> with a leading underscore is reserved to the implementation in the
    >> global namespace. _items_h_ is in the global namespace.

    >
    > what is wrong with it?


    _items_h_ starts with an underscore.

    > This is an avanced technique used in proffesional libraries to prevent
    > probable linker errors generated by repetition.It also decreases
    > compile time.


    Yes, but there are two rules:

    1. Never use a name starting with an underscore in the global namespace.
    2. Never use a name starting with an underscore followed by a capital
    letter, or a name containing __ in _any_ namespace.

    Include guards are very handy, but name them properly.

    --
    rbh
    Robert Bauck Hamar, Jun 3, 2007
    #7
  8. Devon Null

    Daniel T. Guest

    terminator <> wrote:

    > both forms can be used for ctors but the later is better when const
    > data members exist and the former is needed when members have to be
    > assigned assciated values:
    >
    > int f(int,int);//A big function
    >
    > class A{
    > public:
    > const int m;
    > int n,p;
    > A(int i,int j):
    > p(0),
    > m(f(i,j))//const must be initialized here.
    > {n=m;};/*if n is initailized in the initializer list f is called
    > twice which time expensive.*/
    > };


    I try to avoid such micro-optimizations unless profiling has shown that
    they are necessary. For this specific case, if the function has no side
    effects, I expect the compiler would be smart enough to cache the return
    value for the second use.
    Daniel T., Jun 3, 2007
    #8
  9. Devon Null

    Pete Becker Guest

    terminator wrote:
    > On Jun 2, 11:51 pm, red floyd <> wrote:
    >> Devon Null wrote:
    >>> I was simply wondering if this was a mal-formed class header:
    >>> #ifndef _items_h_
    >>> #define _items_h_

    >> Yes, you are malformed right here. Per the Standard, any identifier
    >> with a leading underscore is reserved to the implementation in the
    >> global namespace. _items_h_ is in the global namespace.

    >
    > what is wrong with it?
    > This is an avanced technique used in proffesional libraries to prevent
    > probable linker errors generated by repetition.It also decreases
    > compile time.
    >


    It's not at all advanced. Every header should have include guards. The
    problem it solves is repeating definitions at compile time, which
    produces compile-time errors, not linker errors. The problem with this
    particular example, as has been pointed out in several other messages,
    is the name of the guard.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
    Pete Becker, Jun 3, 2007
    #9
  10. Devon Null

    terminator Guest

    On Jun 3, 8:46 am, "Daniel T." <> wrote:
    > terminator <> wrote:
    > > both forms can be used for ctors but the later is better when const
    > > data members exist and the former is needed when members have to be
    > > assigned assciated values:

    >
    > > int f(int,int);//A big function

    >
    > > class A{
    > > public:
    > > const int m;
    > > int n,p;
    > > A(int i,int j):
    > > p(0),
    > > m(f(i,j))//const must be initialized here.
    > > {n=m;};/*if n is initailized in the initializer list f is called
    > > twice which time expensive.*/
    > > };

    >
    > I try to avoid such micro-optimizations unless profiling has shown that
    > they are necessary. For this specific case, if the function has no side
    > effects, I expect the compiler would be smart enough to cache the return
    > value for the second use.- Hide quoted text -
    >
    > - Show quoted text -


    you pointed to the side effects ;that is exactly what I mean ,and
    since there is no way for the compiler to guess the existance of such
    side effects it must not censor your code-or cache the value as you
    wrote.

    regards
    terminator, Jun 7, 2007
    #10
  11. Devon Null

    terminator Guest

    On Jun 3, 3:23 am, Robert Bauck Hamar <> wrote:
    > terminator wrote:
    > > On Jun 2, 11:51 pm, red floyd <> wrote:
    > >> Devon Null wrote:
    > >>> I was simply wondering if this was a mal-formed class header:
    > >>> #ifndef _items_h_
    > >>> #define _items_h_
    > >> Yes, you are malformed right here. Per the Standard, any identifier
    > >> with a leading underscore is reserved to the implementation in the
    > >> global namespace. _items_h_ is in the global namespace.

    >
    > > what is wrong with it?

    >
    > _items_h_ starts with an underscore.
    >
    > > This is an avanced technique used in proffesional libraries to prevent
    > > probable linker errors generated by repetition.It also decreases
    > > compile time.

    >
    > Yes, but there are two rules:
    >
    > 1. Never use a name starting with an underscore in the global namespace.
    > 2. Never use a name starting with an underscore followed by a capital
    > letter, or a name containing __ in _any_ namespace.
    >
    > Include guards are very handy, but name them properly.
    >
    > --
    > rbh


    header guards from mainstream libraries that I have faced , all have
    underscored guards. In fact since gaurds are not intended to be used
    more than a few times - in header related stuff only - , they are the
    best candidates for dirty names .This way good names can be reserved
    for more important things which are supposed to be introduced in
    global namespace.

    regards
    terminator, Jun 7, 2007
    #11
  12. Devon Null

    James Kanze Guest

    On Jun 7, 2:53 pm, terminator <> wrote:
    > On Jun 3, 3:23 am, Robert Bauck Hamar <> wrote:


    > > terminator wrote:
    > > > On Jun 2, 11:51 pm, red floyd <> wrote:
    > > >> Devon Null wrote:
    > > >>> I was simply wondering if this was a mal-formed class header:
    > > >>> #ifndef _items_h_
    > > >>> #define _items_h_
    > > >> Yes, you are malformed right here. Per the Standard, any identifier
    > > >> with a leading underscore is reserved to the implementation in the
    > > >> global namespace. _items_h_ is in the global namespace.


    > > > what is wrong with it?


    > > _items_h_ starts with an underscore.


    > > > This is an avanced technique used in proffesional libraries to prevent
    > > > probable linker errors generated by repetition.It also decreases
    > > > compile time.


    > > Yes, but there are two rules:


    > > 1. Never use a name starting with an underscore in the global namespace.
    > > 2. Never use a name starting with an underscore followed by a capital
    > > letter, or a name containing __ in _any_ namespace.


    > > Include guards are very handy, but name them properly.


    > header guards from mainstream libraries that I have faced , all have
    > underscored guards. In fact since gaurds are not intended to be used
    > more than a few times - in header related stuff only - , they are the
    > best candidates for dirty names .This way good names can be reserved
    > for more important things which are supposed to be introduced in
    > global namespace.


    Unless the library is part of the implementation, such names are
    illegal, and result in undefined behavior.

    Many basic libraries (e.g. Posix) do consider themselves "part
    of the implementation". Third party libraries which don't,
    however, are in error if they use such names. Or maybe the
    fact that they use such names is a signal that they do consider
    themselves as an extention of the implementation. (At any rate,
    I tend to consider things like the data base library as "part of
    the implementation.")

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 8, 2007
    #12
  13. Devon Null

    Gavin Deane Guest

    On 7 Jun, 13:53, terminator <> wrote:
    > On Jun 3, 3:23 am, Robert Bauck Hamar <> wrote:
    > > Yes, but there are two rules:
    > > 1. Never use a name starting with an underscore in the global namespace.
    > > 2. Never use a name starting with an underscore followed by a capital
    > > letter, or a name containing __ in _any_ namespace.

    >
    > > Include guards are very handy, but name them properly.

    >
    > header guards from mainstream libraries that I have faced , all have
    > underscored guards. In fact since gaurds are not intended to be used
    > more than a few times - in header related stuff only - , they are the
    > best candidates for dirty names .This way good names can be reserved
    > for more important things which are supposed to be introduced in
    > global namespace.


    The point is not whether the names are sufficiently dirty to avoid
    name collisions. The point is that, unless these libraries are part of
    the implementation, they are invading the "namespace" set aside by the
    standard for the sole use of the implementation, and that is illegal.

    Since include guards are #define'd macro names, the best way to avoid
    name clashes between them and the rest of your code is whatever you
    normally do to prevent macro names clashing with code. The most common
    example I've seen is that macro names (including include guards) are
    always ALL_CAPS and everything else is never ALL_CAPS, but any naming
    convention that creates a separate "namespace" for macros is
    sufficient (as long as it doesn't invade the implementation's
    namespace).

    And, of course, you can have naming conventions within that to protect
    include guard names from other macros if you want. For example,
    include guards always ending in _H and other macros never ending in
    _H. But again, any naming convention works as long as it doesn't break
    the two rules above.

    Gavin Deane
    Gavin Deane, Jun 8, 2007
    #13
  14. Devon Null

    terminator Guest

    On Jun 8, 11:12 am, James Kanze <> wrote:
    > On Jun 7, 2:53 pm, terminator <> wrote:
    >
    >
    >
    >
    >
    > > On Jun 3, 3:23 am, Robert Bauck Hamar <> wrote:
    > > > terminator wrote:
    > > > > On Jun 2, 11:51 pm, red floyd <> wrote:
    > > > >> Devon Null wrote:
    > > > >>> I was simply wondering if this was a mal-formed class header:
    > > > >>> #ifndef _items_h_
    > > > >>> #define _items_h_
    > > > >> Yes, you are malformed right here. Per the Standard, any identifier
    > > > >> with a leading underscore is reserved to the implementation in the
    > > > >> global namespace. _items_h_ is in the global namespace.
    > > > > what is wrong with it?
    > > > _items_h_ starts with an underscore.
    > > > > This is an avanced technique used in proffesional libraries to prevent
    > > > > probable linker errors generated by repetition.It also decreases
    > > > > compile time.
    > > > Yes, but there are two rules:
    > > > 1. Never use a name starting with an underscore in the global namespace.
    > > > 2. Never use a name starting with an underscore followed by a capital
    > > > letter, or a name containing __ in _any_ namespace.
    > > > Include guards are very handy, but name them properly.

    > > header guards from mainstream libraries that I have faced , all have
    > > underscored guards. In fact since gaurds are not intended to be used
    > > more than a few times - in header related stuff only - , they are the
    > > best candidates for dirty names .This way good names can be reserved
    > > for more important things which are supposed to be introduced in
    > > global namespace.

    >
    > Unless the library is part of the implementation, such names are
    > illegal, and result in undefined behavior.
    >
    > Many basic libraries (e.g. Posix) do consider themselves "part
    > of the implementation". Third party libraries which don't,
    > however, are in error if they use such names. Or maybe the
    > fact that they use such names is a signal that they do consider
    > themselves as an extention of the implementation. (At any rate,
    > I tend to consider things like the data base library as "part of
    > the implementation.")
    >
    > --
    > James Kanze (GABI Software) email:
    > Conseils en informatique orientée objet/
    > Beratung in objektorientierter Datenverarbeitung
    > 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34- Hide quoted text -
    >
    > - Show quoted text -


    please inform me of the disadvantages of having such form of
    guards.These are possible combinations of legal characters ,why not to
    device them?? are they reserved for none-portable issues only?

    regards,
    FM
    terminator, Jun 9, 2007
    #14
  15. Devon Null

    Gavin Deane Guest

    On 9 Jun, 20:59, terminator <> wrote:
    > On Jun 8, 11:12 am, James Kanze <> wrote:
    > > > On Jun 3, 3:23 am, Robert Bauck Hamar <> wrote:
    > > > > Yes, but there are two rules:
    > > > > 1. Never use a name starting with an underscore in the global namespace.
    > > > > 2. Never use a name starting with an underscore followed by a capital
    > > > > letter, or a name containing __ in _any_ namespace.
    > > > > Include guards are very handy, but name them properly.


    <snip>

    > > Unless the library is part of the implementation, such names are
    > > illegal, and result in undefined behavior.


    <snip>

    > please inform me of the disadvantages of having such form of
    > guards.These are possible combinations of legal characters ,why not to
    > device them?? are they reserved for none-portable issues only?


    Please trim your posts to only include sufficient context to make the
    post comprehensible. And please don't quote signatures, or the "quoted
    text" garbage that Google inserts. Thanks.

    Your answer is in the discussion above. Using names reserved to the
    implementation results in undefined behaviour. That's it. That's all
    the disadvantage you need. That statement alone should be sufficient
    reason for you to avoid such names.

    comp.lang.c++ discusses *what* is in the C++ standard. As far as
    *what* goes, that's all there is to it. However, you are asking *why*
    - and there is generally a reason for these things. One could
    speculate in this case that the rules above give implementors a
    separate "namespace" they can use. If they only use the names that are
    reserved to them, and you never use the names that are reserved to
    them, you can be confident that you won't suffer name clashes with the
    implementation. If one didn't want to speculate, comp.std.c++ is a
    more topical place to discuss *why* the C++ standard is the way it is.

    Gavin Deane
    Gavin Deane, Jun 10, 2007
    #15
  16. Devon Null

    James Kanze Guest

    On Jun 9, 9:59 pm, terminator <> wrote:
    > On Jun 8, 11:12 am, James Kanze <> wrote:
    > > On Jun 7, 2:53 pm, terminator <> wrote:
    > > > On Jun 3, 3:23 am, Robert Bauck Hamar <> wrote:
    > > > > terminator wrote:
    > > > > > On Jun 2, 11:51 pm, red floyd <> wrote:
    > > > > >> Devon Null wrote:
    > > > > >>> I was simply wondering if this was a mal-formed class header:
    > > > > >>> #ifndef _items_h_
    > > > > >>> #define _items_h_
    > > > > >> Yes, you are malformed right here. Per the Standard, any identifier
    > > > > >> with a leading underscore is reserved to the implementation in the
    > > > > >> global namespace. _items_h_ is in the global namespace.
    > > > > > what is wrong with it?
    > > > > _items_h_ starts with an underscore.
    > > > > > This is an avanced technique used in proffesional libraries to prevent
    > > > > > probable linker errors generated by repetition.It also decreases
    > > > > > compile time.
    > > > > Yes, but there are two rules:
    > > > > 1. Never use a name starting with an underscore in the global namespace.
    > > > > 2. Never use a name starting with an underscore followed by a capital
    > > > > letter, or a name containing __ in _any_ namespace.
    > > > > Include guards are very handy, but name them properly.
    > > > header guards from mainstream libraries that I have faced , all have
    > > > underscored guards. In fact since gaurds are not intended to be used
    > > > more than a few times - in header related stuff only - , they are the
    > > > best candidates for dirty names .This way good names can be reserved
    > > > for more important things which are supposed to be introduced in
    > > > global namespace.


    > > Unless the library is part of the implementation, such names are
    > > illegal, and result in undefined behavior.


    > > Many basic libraries (e.g. Posix) do consider themselves "part
    > > of the implementation". Third party libraries which don't,
    > > however, are in error if they use such names. Or maybe the
    > > fact that they use such names is a signal that they do consider
    > > themselves as an extention of the implementation. (At any rate,
    > > I tend to consider things like the data base library as "part of
    > > the implementation.")


    > please inform me of the disadvantages of having such form of
    > guards.


    The disadvantage is that they are illegal, and using them causes
    your code to have undefined behavior.

    > These are possible combinations of legal characters ,why not to
    > device them?? are they reserved for none-portable issues only?


    The reason the standard bans them is precisely to give the
    implememters a set of names they can use, without risk of
    conflicts with your code. Thus, for example, some library
    header might contain something like:

    class SomeStandardClass
    {
    private:
    int _items_h_
    } ;

    Now what happens if you include that library header in your
    header?

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 10, 2007
    #16
  17. Devon Null

    Daniel T. Guest

    On Jun 7, 8:46 am, terminator <> wrote:
    > On Jun 3, 8:46 am, "Daniel T." <> wrote:


    > > > int f(int,int);//A big function
    > > >
    > > > class A{
    > > > public:
    > > > const int m;
    > > > int n,p;
    > > > A(int i,int j):
    > > > p(0),
    > > > m(f(i,j))//const must be initialized here.
    > > > {n=m;};/*if n is initailized in the initializer list f is
    > > > called
    > > > twice which time expensive.*/
    > > > };

    >
    > > I try to avoid such micro-optimizations unless profiling has
    > > shown that they are necessary. For this specific case, if the
    > > function has no side effects, I expect the compiler would be
    > > smart enough to cache the return value for the second use.-

    >
    > you pointed to the side effects ;that is exactly what I mean ,and
    > since there is no way for the compiler to guess the existance of
    > such side effects it must not censor your code-or cache the value
    > as you wrote.


    I disagree that "there is no way for the compiler to guess the
    existance of such side effects". If the function deals with only its
    parameters and local variables, there is no way for it to *have* side
    effects.
    Daniel T., Jun 11, 2007
    #17
  18. Devon Null

    terminator Guest

    On Jun 11, 5:06 pm, "Daniel T." <> wrote:
    > On Jun 7, 8:46 am, terminator <> wrote:
    > > > > int f(int,int);//A big function

    >
    > > > > class A{
    > > > > public:
    > > > > const int m;
    > > > > int n,p;
    > > > > A(int i,int j):
    > > > > p(0),
    > > > > m(f(i,j))//const must be initialized here.
    > > > > {n=m;};/*if n is initailized in the initializer list f is
    > > > > called
    > > > > twice which time expensive.*/
    > > > > };

    >
    > > > I try to avoid such micro-optimizations unless profiling has
    > > > shown that they are necessary. For this specific case, if the
    > > > function has no side effects, I expect the compiler would be
    > > > smart enough to cache the return value for the second use.-

    >
    > > you pointed to the side effects ;that is exactly what I mean ,and
    > > since there is no way for the compiler to guess the existance of
    > > such side effects it must not censor your code-or cache the value
    > > as you wrote.

    >
    > I disagree that "there is no way for the compiler to guess the
    > existance of such side effects". If the function deals with only its
    > parameters and local variables, there is no way for it to *have* side
    > effects


    I have commented 'f' to be a large function whose value cannot be
    deduced before excution specifically 'f' can be a random value
    generating function.I would delare 'f' as 'inline' if it was a simple
    value-forcastable function;this would motivate the compiler for
    optimization. Moreover what I wrote is not a micro-
    optimization.consider these two cases:
    1. 'f' is an input function
    2. 'f' is a random-return function
    the return of 'f' will be different on every call in these cases.

    regards,
    FM
    terminator, Jun 12, 2007
    #18
  19. Devon Null

    terminator Guest

    On Jun 11, 1:41 am, James Kanze <> wrote:
    >
    > The disadvantage is that they are illegal, and using them causes
    > your code to have undefined behavior.


    Illegal? You keep repeating this sentence.Please define illegal; I
    think that must mean something syntactically wrong, but if you mean
    none-std then I would humblly ask why is it none-std?

    By the way thanks to everyone I have found that underscored names are
    supposed to be used by implementors and others including third-party
    libraries had better keep off them(it is not a must).

    regards,
    FM.
    terminator, Jun 12, 2007
    #19
  20. Devon Null

    Daniel T. Guest

    terminator <> wrote:

    > On Jun 11, 5:06 pm, "Daniel T." <> wrote:
    > > On Jun 7, 8:46 am, terminator <> wrote:
    > > > > > int f(int,int);//A big function

    > >
    > > > > > class A{
    > > > > > public:
    > > > > > const int m;
    > > > > > int n,p;
    > > > > > A(int i,int j):
    > > > > > p(0),
    > > > > > m(f(i,j))//const must be initialized here.
    > > > > > {n=m;};/*if n is initailized in the initializer list f is
    > > > > > called
    > > > > > twice which time expensive.*/
    > > > > > };

    > >
    > > > > I try to avoid such micro-optimizations unless profiling has
    > > > > shown that they are necessary. For this specific case, if the
    > > > > function has no side effects, I expect the compiler would be
    > > > > smart enough to cache the return value for the second use.-

    > >
    > > > you pointed to the side effects ;that is exactly what I mean ,and
    > > > since there is no way for the compiler to guess the existance of
    > > > such side effects it must not censor your code-or cache the value
    > > > as you wrote.

    > >
    > > I disagree that "there is no way for the compiler to guess the
    > > existance of such side effects". If the function deals with only its
    > > parameters and local variables, there is no way for it to *have* side
    > > effects

    >
    > I have commented 'f' to be a large function whose value cannot be
    > deduced before excution specifically 'f' can be a random value
    > generating function.I would delare 'f' as 'inline' if it was a simple
    > value-forcastable function;this would motivate the compiler for
    > optimization. Moreover what I wrote is not a micro-
    > optimization.consider these two cases:
    > 1. 'f' is an input function
    > 2. 'f' is a random-return function
    > the return of 'f' will be different on every call in these cases.


    In that case, calling f more than once will probably change the behavior
    of the program and we are in a whole different world. Your initial
    comment that you are doing it because it is "time expensive" is then in
    error, your not calling it twice because that would be an error
    regardless of the time it takes.

    If that is the case, then you could do something like this:

    class A {
    const int m;
    int n;
    public:
    A( int i, int j ): m( f( i, j ) ), n( m ) { }
    };

    Based on your earlier post, you are under the impression that assigning
    in the body of the constructor is required under certain circumstances,
    I don't think that is the case.
    Daniel T., Jun 12, 2007
    #20
    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. Frank Rizzo
    Replies:
    4
    Views:
    470
    Frank Rizzo
    Jan 13, 2004
  2. Craig S. Ugoretz
    Replies:
    0
    Views:
    402
    Craig S. Ugoretz
    Feb 18, 2004
  3. Michael Sparks
    Replies:
    2
    Views:
    268
    Max M
    Jul 7, 2003
  4. Ian Pilcher

    The Wisdom of 6.5.5(6)

    Ian Pilcher, Feb 24, 2005, in forum: C Programming
    Replies:
    4
    Views:
    364
    Tim Rentsch
    Feb 25, 2005
  5. Devon Null
    Replies:
    15
    Views:
    481
    Devon Null
    Jun 8, 2007
Loading...

Share This Page