Thread: including namespaces

  1. #31
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    This is just for fun, it is not in any way an attempt to say that using std::count is bad. But there are still the same types of errors that could occur - name conflicts or unknowingly using the wrong name. Here is my contrived example.
    Code:
    // In MyClass.h
    #ifndef MYCLASS_H_
    #define MYCLASS_H_
    
    #include <iostream>
    using std::cout;
    using std::endl;
    #include <algorithm>
    using std::count;
    
    class MyClass
    {
    public:
        MyClass() {
            sizeOfA = 8;
            A = new int[sizeOfA];
            for (int i=0; i<sizeOfA; i++)
                A[i] = (i%3)+1;
        }
        void PrintItemCount(int item) {
            cout << item << " count: " << count(A, A + sizeOfA, item) << endl;
        }
    private:
        int* A;
        int sizeOfA;
    };
    #endif // MYCLASS_H_
    Code:
    // In HelperFunc.h
    #ifndef HELPER_FUNC_H_
    #define HELPER_FUNC_H_
    int count(int* array1, int* array2, int numElements)
    {
        int sum = 0;
        for (int i = 0; i < numElements; i++)
        {
            sum += array1[i];
            sum += array2[i];
        }
        return sum;
    }
    #endif // HELPER_FUNC_H_
    Code:
    // In main.cpp
    
    // Maybe this header is included by another header deep in a library somewhere.
    #include "MyClass.h"
    
    // Oops! Forgot to #include "HelperFunc.h"
    
    #include <iostream>
    using std::cout;
    using std::endl;
    
    int main()
    {
        int array1[] = { 2, 0, 4, 6, 2, 3, 2, -7 };
        int array2[] = { 5, 8, 0, 4, 1, 1, -4, 2 };
        // Try to use the count in HelperFunc.h
        cout << count(array1, array2, 8) << endl;
    }
    Result: undefined behavior - on my machine it crashed. Since HelperFunc.h wasn't included, the code found the std::count included in the MyClass.h header file. Because the using std::count was put in that header file, the main code used the algorithm count instead of the intended one.

    This is more of an indictment on putting using directives in header files, but there you go.

  2. #32
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Nice example jlou... You saved me from having to think later on.

    And, the problem may just throw a compile-time error, or crash, and not be a subtle little bug, but it is nice to be able to reuse those names for your own functions/objects on occasion.

  3. #33
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Any standard-conforming compiler would issue an error "ambiguous command", or something equivalent. The "real" function would not be called.
    Since MSVC isn't a standard-conforming compiler, it would (theoretically).

    The question is currently whether using-declarations like this one

    using N::func;

    can result in the wrong func being called somewhere.
    And since MSVC isn't a standard-compliant compiler, it would seem that it can - and that was the point I was trying to make
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #34
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    OK jlou, but your example has using-declaration in header files, which is bad for other reasons as well.

    What I wanted (I was unclear) is an example of the same phenomenon, but only with using-declarations in source files (if it exists).


    Since MSVC isn't a standard-conforming compiler, it would (theoretically).
    Umm, MSVC++ does issue an error.
    What version are you using? The lastest three version are quite conforming and this is a relatively basic feature.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  5. #35
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Of course it exists Sang-drax, but at some point it crosses over into the realm of "that would never happen - I'm not stupid enough to ever do that." I think bringing in a single name from a namespace is perfectly acceptable, preferably inside the scope of a function or loop where it is being used. Bringing in a single name from a namespace at the top of a source file can also be acceptable in my personal opinion, but I don't think it would necessary in most cases, especially for the std namespace.

    So, here is my example of a using directive in a source file that only brings in a single name and causes unwanted behavior.
    Code:
    // In HelperFunc.h
    #ifndef HELPER_FUNC_H_
    #define HELPER_FUNC_H_
    int count(int* array1, int* array2, int numElements)
    {
        int sum = 0;
        for (int i = 0; i < numElements; i++)
        {
            sum += array1[i];
            sum += array2[i];
        }
        return sum;
    }
    #endif // HELPER_FUNC_H_
    Code:
    // In main.cpp
    // Oops! Forgot to #include "HelperFunc.h"
    
    // In main.cpp
    #include <iostream>
    #include <algorithm>
    
    int main()
    {
        int array1[] = { 2, 0, 4, 6, 2, 3, 2, -7 };
        int array2[] = { 5, 8, 0, 4, 1, 1, -4, 2 };
    
        using std::cout;
        using std::endl;
        using std::count;
    
        // Use std::count
        cout << count(array1, array1 + sizeof(array1), 2) << endl;
    
        // ...
    
        // Try to use the count in HelperFunc.h
        cout << count(array1, array2, 8) << endl;
    }
    Result: undefined behavior. On my machine it crashes.

  6. #36
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Result: undefined behavior. On my machine it crashes.
    Your last example results in undefined behavior even if HelperFunc.h is included.
    std::count is called in both cases even if the header is included.


    What I didn't realize at first was:
    Code:
    namespace A
    {
      int f(int);
    }
     
    namespace B
    {
      int f(char);
    }
     
    using A::f;
    using B::f;  //Possible because the two fs are a little different
    But if one using-declaration is omitted, all calls to f will revert to the other one because the functions are compatible.
    Last edited by Sang-drax; 08-06-2004 at 04:09 PM.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  7. #37
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Really? Well, I guess the using directive is more dangerous than I thought.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Including extra .cpp files visual2008
    By Cathalo in forum C++ Programming
    Replies: 9
    Last Post: 06-16-2009, 03:29 AM
  2. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  3. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  4. Reading a line including blanks
    By Ec4U2du in forum C++ Programming
    Replies: 4
    Last Post: 11-13-2002, 07:32 PM
  5. namespaces
    By Mario in forum C++ Programming
    Replies: 3
    Last Post: 05-27-2002, 02:57 PM