CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Using #define with colons (e.g. with a namespace)

    This is a follow-up regarding an issue I've had using ofstream in a cross-platform app (I started an earlier thread but I prematurely marked it as 'resolved')

    For creating an ofstream (in posix) we have some openmode enums looking something like this:-

    Code:
    enum openmode
    {
    	in,
    	out,
    	ate,
    	app,
    	trunc,
    	bin
    };
    They get declared in a namespace (or possibly a class) called ios. Microsoft uses something similar- but for MSVC the equivalent enums would be these:-

    Code:
    enum openmode
    {
    	in,
    	out,
    	ate,
    	app,
    	trunc,
    	binary  // <--- Note that this one is different !!
    };
    So for a cross platform app (which might need to open files in binary mode) I'd need stuff like this all over the place:-

    Code:
    #ifdef _MSC_VER
          ofstream whatever ("wherever", ios::binary);
    #else
          ofstream whatever ("wherever", ios::bin);
    #endif
    which is obviously a bit messy! I can (kinda) resolve it with a suitable #define:-

    Code:
    #ifdef _MSC_VER
         #define bin binary
    #endif
    but that's also messy because now, any use of the word bin will get changed to binary. Ideally I'd like to do this:-

    Code:
    #ifdef _MSC_VER
         #define ios::bin ios::binary
    #endif
    but that gets rejected by the compiler... Is there any clever way to set this up such that all occurrences of ios::bin will get changed to ios::binary - but any other occurrences of bin would be unaffected?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  2. #2
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Using #define with colons (e.g. with a namespace)

    Quote Originally Posted by John E View Post
    Is there any clever way to set this up such that all occurrences of ios::bin will get changed to ios::binary - but any other occurrences of bin would be unaffected?
    You could define a global constant for the value.
    Code:
    namespace Something {
    #ifdef _MSC_VER
      const auto Binary = std::ios::binary;
    #else
      const auto Binary = std::ios::bin;
    #endif
    } // namespace Something
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  3. #3
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Using #define with colons (e.g. with a namespace)

    Code:
    #include <fstream>
    
    #ifdef _MSC_VER
    #define IOS_BINARY ios::binary
    #else
    #define IOS_BINARY ios::bin
    #endif
    
    int main()
    {
        std::ofstream whatever("wherever", std::IOS_BINARY);
        whatever.close();
        return 0;
    }
    Best regards,
    Igor

  4. #4
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Using #define with colons (e.g. with a namespace)

    non #define solution. that makes existing code work with VS.

    Code:
    #include <fstream>
    
    #ifdef _MSC_VER
    namespace std
    {
    	namespace ios
    	{
    		const std::ios_base::openmode bin = binary;
    	};
    };
    #endif
    
    int main()
    {
        std::ofstream whatever("wherever", std::ios:bin);
        whatever.close();
        return 0;
    }

  5. #5
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Using #define with colons (e.g. with a namespace)

    Quote Originally Posted by OReubens View Post
    Code:
    #include <fstream>
    
    #ifdef _MSC_VER
    namespace std
    {
    	namespace ios
    	{
    		const std::ios_base::openmode bin = binary;
    	};
    };
    #endif
    That's a good suggestion OReubens but I already tried it yesterday. I'm not sure if it'd work in more recent versions of MSVC but for the version I'm using (VC 8) it gives me:-

    Code:
    error C2757: 'ios' : a symbol with this name already exists and therefore this name cannot be used as a namespace name
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  6. #6
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Using #define with colons (e.g. with a namespace)

    Quote Originally Posted by John E View Post
    [...]but for the version I'm using (VC 8) it gives me:-
    because ios is not a namespace and openmode's are not enums. As said in the other thread, either you're using a highly non compliant compiler or 'binary' should work everywhere ( with no effect on *nix ).

  7. #7
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Using #define with colons (e.g. with a namespace)

    Quote Originally Posted by superbonzo View Post
    you're using a highly non compliant compiler
    Well, GCC really complains about ios::bin:

    Code:
    #include <fstream>
    
    int main()
    {
        std::ofstream whatever("wherever", std::ios::bin);
        whatever.close();
        return 0;
    }
    Code:
    [xxxx@xxxx-iv 1]$ g++ 1.cpp -o a.out
    1.cpp: In function ‘int main()’:
    1.cpp:5:37: error: ‘bin’ is not a member of ‘std::ios {aka std::basic_ios<char>}’
      std::ofstream whatever("wherever", std::ios::bin);
                                         ^
    Last edited by Igor Vartanov; September 15th, 2015 at 03:23 AM.
    Best regards,
    Igor

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