CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    This surprised me...

    Someone at work discovered this:
    Code:
    enum Whatever
    {
    	One, Two
    };
    
    Whatever Whatever;
    
    int main()
    {
    	Whatever = Two;
    }
    Comeau is quite happy with it.

    I presume it comes about because of some complicated interaction of the various name lookup rules, but it strikes me as a potential cause for sleepless nights trying to trace a bug...
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  2. #2
    Join Date
    Aug 2002
    Location
    Cluj-Napoca,Romania
    Posts
    3,496

    Re: This surprised me...

    MSVC 6.0 has no problems either with this code.
    Har Har

  3. #3
    Join Date
    Apr 2003
    Location
    Athens, Greece
    Posts
    1,094

    Re: This surprised me...

    VC++ 7.0 compiles it also.
    I do not have the C++ standard handy. Allowing this can be confusing I guess.
    Extreme situations require extreme measures

  4. #4
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    Thumbs up Re: This surprised me...

    Even this is allowed by Comeau as well as VC++ 6.0
    Code:
    #include <iostream>
    class Whatever{
    	public:
    		int i;
    };
    int main()
    {
    	Whatever Whatever;
    	Whatever.i = 20;
    	std::cout << Whatever.i;
    	return 0;
    }
    It allows the name of the class to be the name of the Object of that class. Is this what you are pointing to? It can be a misleading though I am unable to find an instance, yet.

    Tweaking it a little bit more, I tried this:
    Code:
    #include <iostream>
    class Whatever{
    	public:
    		int i;
    };
    class AnotherWhatever{
    	public:
    		static int i;
    };
    static int i = 10;
    int main()
    {
    	Whatever AnotherWhatever;
    	AnotherWhatever.i = 20;
    	std::cout << AnotherWhatever.i;
    	return 0;
    }
    It considers AnotherWhatever as the object and it does not allow me to get to the class with the static member no matter what I do. So, I guess this wouldnt result in ambiguities from a coder's viewpoint - provided this is what you are referring to in the enum example.
    Last edited by exterminator; September 8th, 2005 at 08:16 AM.

  5. #5
    Join Date
    Jun 2005
    Posts
    15

    Re: This surprised me...

    This also works for structs and classes.

    I dont think it is illegal C code, but it should be with a severe penalty!

    I found a quirk with this using MSVC 6:

    enum Whatever
    {
    One, Two
    };

    void printwhatever (Whatever Whatever){
    if(Whatever == Two)
    printf("two");
    }

    Whatever Whatever;

    int main(int argc, char* argv[])
    {
    Whatever = Two;
    printwhatever(Two);
    return 0;
    }

    this works, but if the global Whatever is declared before the function it doesnt, i suppose this is a compiler bug? As iam asuming that it doent break the rules of C.

  6. #6
    Join Date
    May 2004
    Location
    45,000FT Above Nevada
    Posts
    1,539

    Re: This surprised me...

    You can give an enumeration a type name and use the type name to define variables. For example:
    Code:
    enum card_suit
    {
        CLUBS,
        DIAMONDS,
        HEARTS,
        SPADES
    } card1;
    
    enum card_suit card2, pack[52];
    Here, card1 and card2 are variables of type enum card_suit, and pack is an array of 52 elements of type enum card_suit.

    As variables of this type, they CAN be assigned only the constants CLUBS, DIAMONDS, HEARTS, or SPADES. NO other assigment is legal:
    Code:
    card1 = CLUBS;    /* legal */
    pack[5] = card2 = DIAMONDS;   /* legal */
    card2 = 100;   /* ERROR  */
    Only a few operations are possible with variables of an enumerated type. They can be assigned one of the constants in the enum series, they can be assigned values from other expressions of the same type, and they can be compared to other expressions of the same type.
    Last edited by Vanaj; September 8th, 2005 at 01:48 PM.
    Jim
    ATP BE400 CE500 (C550B-SPW) CE560XL MU300 CFI CFII

    "The speed of non working code is irrelevant"... Of course that is just my opinion, I could be wrong.

    "Nothing in the world can take the place of persistence. Talent will not; nothing is more common than unsuccessful men with talent. Genius will not; unrewarded genius is almost a proverb. Education will not; the world is full of educated derelicts. Persistence and determination are omnipotent. The slogan 'press on' has solved and always will solve the problems of the human race."...Calvin Coolidge 30th President of the USA.

  7. #7
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: This surprised me...

    It becomes a problem when an ambiguity arises.

    Code:
    class X
    {
    public:
      explicit X ( Whatever ) ;
    };
    
    int func()
    {
       Whatever Whatever;
    
       X anX( Whatever ); // ambiguous
    };

  8. #8
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: This surprised me...

    Quote Originally Posted by Graham
    Someone at work discovered this:
    Code:
    enum Whatever
    {
    	One, Two
    };
    
    Whatever Whatever;
    
    int main()
    {
    	Whatever = Two;
    }
    Comeau is quite happy with it.

    I presume it comes about because of some complicated interaction of the various name lookup rules, but it strikes me as a potential cause for sleepless nights trying to trace a bug...
    There are limitations to name redefinition:
    Quote Originally Posted by class.nested.type
    -3- Change: In C++, a typedef name may not be redefined in a class declaration after being used in the declaration
    Example:

    typedef int I;
    struct S {
    I i;
    int I; // valid C, invalid C++
    };


    Rationale: When classes become complicated, allowing such a redefinition after the type has been used can create confusion for C++ programmers as to what the meaning of 'I' really is.
    Effect on original feature: Deletion of semantically well-defined feature.
    Difficulty of converting: Semantic transformation. Either the type or the struct member has to be renamed.
    How widely used: Seldom.
    However, name redefinition is useful for local variables, because local variables may be numerous and have insignifiant names.
    If, there was an error when a type was reused as local variable, it would be problematic when adding new types, and seeing that they conflict with some local variables of already-well-written functions.
    In my point of view, the body of a function must be opaque for the remaining of the code, and must not conflict.

    But, i think that it is bad to redefine a name, for a global variable, because the global variable is not opaque.

  9. #9
    Join Date
    Sep 2004
    Location
    A Planet Called Earth... :-)
    Posts
    835

    Re: This surprised me...

    I just hope people dont start coding like that. Even if they do, i pray that i dont come across such projects.

    I can imagine myself trying to trace some part of program..., come across 'Whatever'.., look at its definition.., and find that - it is also 'Whatever'. I wll probably be searching for its definition scratching my head forever.
    C++ program ran... C++ program crashed... C++ programmer quit !!

    Regards

    Shaq

  10. #10
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: This surprised me...

    Sure, it is bad to use this feature, but it is useful that this feature exists.
    In the same order of idea, a local variable or a class member may have the same name that a global variable.

  11. #11
    Join Date
    Jun 2002
    Location
    Moscow, Russia.
    Posts
    2,176

    Re: This surprised me...

    And it's sometimes OK to use the same name for field and access method (which isn't necessary just returning it). With IDE showing fields using color different from that for other variables, underscores or such seem wrong.
    "Programs must be written for people to read, and only incidentally for machines to execute."

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured