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 33,204 of 33,346   
   fmatthew5876 to All   
   Returning a char* pointer   
   11 Sep 13 19:22:10   
   
   From: fmatthew5876@googlemail.com   
      
   C had a lot of old style functions like this:   
      
   char* foo(/*some_args*/);   
      
   where the returned pointer was a function local static.   
   Of course this is not thread safe so we never do it anymore.   
      
   I'd like to experiment with ways of using stack allocated   
   buffers in order to avoid memory allocations.   
      
   I have a class Foo which has a toString operation like this:   
      
   class Foo {   
     public:   
       //Len must be greater than 16   
       char* toString(char* buf, size_t len) {   
         //Write the stringified representation to buf   
         return buf;   
       }   
       template    
         char* toString(char (&buf)) {   
            //Could static_assert on N here for C++11.   
            return toString(buf, N);   
       }   
   };   
      
   Now I can use it this way:   
      
   Foo foo;   
   char buf[16];   
   printf("FOO IS %s\n", foo.toString(buf));   
      
   Creating this stack buffer by hand is cumbersome. So here   
   is another idea for a toString() overload.   
      
   class Foo {   
   public:   
     char* toString(char* buf, size_t len);   
     template    
       char* toString(char (&buf)[N]) {   
         return toString(buf, N);   
     }   
      
     class Buf {   
       mutable char buf[16];   
       friend class Foo;   
     };   
      
     char* toString(const Buf& buf = Buf()) {   
       return toString(buf.buf, sizeof(buf.buf));   
     }   
   };   
      
   And with that, I can do now do this:   
   printf("FOO IS %s\n", foo.toString());   
      
   A small character array is efficiently allocated on the stack,   
   pass to toString(),written to, passed to printf,   
   and then destroyed when printf() finishes.   
      
   Will this work? In particular, the lifetime of the temporary   
   Buf object created must last until the call to printf is completed.   
      
   One big problem with this interface is people trying   
   to do this:   
   char* p = foo.toString();   
   use(p);   
      
   I'm not sure there is a way to detect and prevent this use case.   
   toString() MUST return a char* for printf to work correctly.   
      
   What do you think? Do you see any holes or potential problems   
   in this design?   
      
   Also please leave iostream and std::string out of this discussion.   
   The former because its slow and doesn't support printf syntax and the   
   second because it allocates memory.   
      
   Thanks!   
      
      
   --   
         [ 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