home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 32,355 of 33,346   
   John Doe to All   
   =?windows-1256?Q?Template_i?= =?windows-   
   03 Jun 12 12:47:48   
   
   From: ab4ag1@hotmail.com   
      
   (Note: Only the introduction is linux specific.)   
   On Linux there are two functions called strerror_r. One can choose   
   between those function using appropriate preprocessor flags. The problem   
   is that the functions have different return types which is why I tried   
   to wrap the handling code in another C++ function. I wanted to hide the   
   distinction using templates.   
      
   The idea is to create template specializations for each implementation   
   and let the compiler decide which one to pick. For some reason g++ 4.5.3   
   always seems to instantiate both methods and I don't know why.   
      
   Here is what I think should happen:   
   1. The compiler evaluates Equals in line 83   
   2. The compiler instantiates Call (on *my* system is true).   
   Call is not instantiated.   
   3. The compiler instantiates Strerror_r because of 2.). Also   
   because of 2.), Strerror_r is never instantiated.   
   4. The compiler sees fitting returns types in line 19, the mismatch in   
   line 36 is ignored.   
      
   Where is my mistake?   
      
   Compiler: g++ 4.5.3   
      
   Error Message:   
   map.cpp: In member function ‘int Strerror_r::posix(int, char*, size_t)’:   
   map.cpp:36:40: error: invalid conversion from ‘char*’ to ‘int’   
      
   (On my system the GNU's strerror_r version is used (char* return type))   
      
      
   Code:   
   #include    
   #include    
   #include  // strerror_r   
      
      
   typedef char* (*Gnu_strerror_r_type)(int, char*, size_t);   
   typedef int (*Posix_strerror_r_type)(int, char*, size_t);   
      
      
   template   
   struct Strerror_r;   
      
      
   template<>   
   struct Strerror_r   
   {   
        int gnu(int error, char* buffer, size_t size)   
        {   
            char* p( strerror_r(error, buffer, size) ); // line 19   
            if( !p || p == buffer )   
                return 0;   
      
            strncpy(buffer, p, size-1);   
            buffer[size-1] = 0;   
            return 0;   
        }   
   };   
      
      
      
   template<>   
   struct Strerror_r   
   {   
        // Why is this instantiated???   
        int posix(int error, char* buffer, size_t size)   
        {   
            return strerror_r(error, buffer, size); // Line 36 here   
        }   
   };   
      
      
      
   template   
   struct Call;   
      
      
   template<>   
   struct Call   
   {   
        Strerror_r s;   
        int execute(int e, char* p, size_t sz) { return s.gnu(e,p,sz); }   
   };   
      
      
      
   template<>   
   struct Call   
   {   
        Strerror_r s;   
        int execute(int e, char* p, size_t sz) { return s.posix(e,p,sz); }   
   };   
      
      
      
   template   
   struct Equals   
   {   
        static const bool value = false;   
   };   
      
      
   template   
   struct Equals   
   {   
        static const bool value = true;   
   };   
      
      
      
   template   
   int my_strerror_r_impl(   
        T, int error, char* buffer, size_t size)   
   {   
        Call::value> c; // line 83   
        return c.execute(error, buffer, size);   
   }   
      
      
      
   int my_strerror_r(int error, char* buffer, size_t size)   
   {   
        return my_strerror_r_impl(&strerror_r, error, buffer, size);   
   }   
      
      
      
   int main()   
   {   
        char buffer[1024];   
        memset(buffer, 0, sizeof(buffer));   
        if( my_strerror_r(ENOSYS, buffer, sizeof(buffer)) < 0 )   
            return 1;   
      
        std::printf( "Message: '%s'\n", buffer );   
   }   
      
      
     		 	   		   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca