Search code examples
c++constantsambiguous

Including constants without functions


I am making a c++ library and I want to include fcntl.h in the header (for the permission constants)

But I have a function called open, the argument list contains classes that can be casted to the fcntl's open argument list types.

That means when i use #include<fcntl.h> I am getting an ambiguous error.

I want the library to be as portable as possible.

I thought of changing the name from open to Open but is there a better solution?

Like including the header without parsing the functions(eg. Just including the constants).


Solution

  • is there a better solution?

    Use a namespace:

    namespace my_lib {
      int open(const char *pathname, int flags);
    }
    

    And to be clear, a library should always declare its functions/classes/constants/etc... in a namespace, not just as a means to fix a specific issue. This way, you avoid potential conflicts with other libraries that users might be including that you have no visibility on.

    Edit: From the followup in the comment, if prefixing things with a namespace gets annoying, you can locally use individual identifiers from a namespace, and that will not be ambiguous, nor will is cause conflicts elsewhere in the code.

    #include <fcntl.h>
    
    namespace my_lib {
        int open(const char *pathname, int flags);
    }
    
    void foo() {
        using my_lib::open;
        
        open("aaa", 0);
    }
    

    You should never resort to using namespace my_lib. However, should you be painted in a corner (e.g. the using namespace is in code you can't change), you can resolve conflicts by explicitly referring to the namespace for the ambiguous symbol.

    #include <fcntl.h>
    
    namespace my_lib {
        void bar();
        int open(const char *pathname, int flags);
    }
    
    using namespace my_lib;
    
    void foo() {
        bar();
    
        // use the open() from fcntl.h
        ::open("aaa", 0);
    
        // Use the open() from my_lib
        ::my_lib::open("aaa", 0);
    }