CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Aug 2008
    Location
    Germany / NRW
    Posts
    37

    Standard C strings

    Hello Folks,

    I have some trouble figuring this out correctly. If you have a function that should
    manipulate a string in some way, you probably do it like this:

    Code:
    wchar_t *strmani(wchar_t *input){
       for(int i=0;i<(int)wcslen(input);i++){
            input[i] = dosomething;
      }
    
      return(input);
    }
    This works well if you call it like this:

    Code:
    wchar_t mybuffer[64];
    wcscpy(mybuffer, L"manipulate me\0");
    strmani(mybuffer);
    It does of course not work if you call strmani() like:
    Code:
    strmani(L"my string without buffer\0");
    It will crash.
    Now I was wondering if you can write a function that handles both, buffers and "plain"
    strings without a buffer defination.
    So I tried this:

    Code:
    wchar_t *strmani(wchar_t *str){
    	wchar_t buf[255];
    	wcscpy_s(buf, 255, str);
    
    	for(int i=0;i<(int)wcslen(buf);i++){
    		buf[i] = dosomething;
    	}
    
    	return(buf);
    }
    For my surprise, this actually works even if you return an address of a local defined variable.
    But I'm not happy with that, some compilers (espcially gnu's) gave me at least a compiler
    warning for exactly that reason.

    So now after all this my question, is this a valid possibility if I don't want to care whether
    someone calls strmani(var) or strmani(L"text")?
    Is there maybe a better solution?

    Thanks in Advance,
    Andy
    Last edited by CatShoe; December 22nd, 2008 at 09:29 AM.

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Standard C strings

    Quote Originally Posted by CatShoe
    Now I was wondering if you can write a function that handles both, buffers and "plain"
    strings without a buffer defination.
    The problem is that a string literal cannot be modified yet your function modifies the string that is passed to it. You do need to provide a buffer for the result to be written to (or use dynamic memory allocation and return a pointer to what was allocated in the function... but then you'll have to manage memory manually unless you return a std::wstring instead).

    Quote Originally Posted by CatShoe
    For my surprise, this actually works even if you return an address of a local defined variable.
    But I'm not happy with that, some compilers (espcially gnu's) gave me at least a compiler
    warning for exactly that reason.
    Yes, you would be relying on undefined behaviour if you tried to use that.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Standard C strings

    Quote Originally Posted by CatShoe View Post
    This works well if you call if like this:
    No it doesn't.
    For my surprise, this actually works even if you return an address of a local defined variable.
    No. Returning the address of a local variable is undefined behaviour. Don't do it.

    Undefined behaviour means that anything can happen. This could mean including working, failing, working sometimes and failing other times, working with one set of compiler options and failing with another set of compiler options.
    But I'm not happy with that, some compilers (espcially gnu's) gave me at least a compiler
    warning for exactly that reason.
    You shouldn't be happy at all -- you shouldn't even be doing it.
    So now after all this my question, is this a valid possibility if I don't want to care whether
    someone calls strmani(var) or strmani(L"text")?
    Is there maybe a better solution?
    The solution is to document to the user that string literals are not accepted. The function is supposed to manipulate the passed-in parameter, therefore a string-literal cannot be passed to the function, as writing to string-literals is also undefined behaviour.

    You also enforce this by making the parameter char* instead of const char*. This tells the user of the function that the input could be changed, and string-literals cannot be accepted. If the user of the function doesn't know this, they need to read up on C programming and read the part concerning string-literals being unmodifiable.

    Regards,

    Paul McKenzie

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Standard C strings

    This sort of quandary is precisely what std::strings and std::wstrings are meant to solve. They'll copy data when necessary and they won't when it's not (assuming fully optimized builds). You have some control over when a copy occurs via choosing pass-by-value or pass-by-reference; if you want a literal string to be a possibility, you'll have to pass by value or const reference (in which case you can't modify it anyway).

  5. #5
    Join Date
    Dec 2008
    Location
    Xi'an China
    Posts
    27

    Re: Standard C strings

    use const to indicate you paramater wouldn't be modified by you function is a better choice.
    Code:
    wchar_t *strmani(const wchar_t *input){
       for(int i=0;i<(int)wcslen(input);i++){
            ...
      }
    
      return(input);
    }
    Last edited by Fireseed; December 23rd, 2008 at 11:27 AM.
    Life is similar to ....., if you cannot resist it, you should relax and enjoy it.

  6. #6
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Standard C strings

    Quote Originally Posted by Fireseed
    use const to indicate you paramater wouldn't be modified by you function is a better choice.
    That choice is not available because the string will be modified by the function.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  7. #7
    Join Date
    Dec 2008
    Location
    Xi'an China
    Posts
    27

    Re: Standard C strings

    Quote Originally Posted by laserlight View Post
    That choice is not available because the string will be modified by the function.
    I means user should not pass a const variable to a non-const paramates.
    Life is similar to ....., if you cannot resist it, you should relax and enjoy it.

  8. #8
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Standard C strings

    This issue is unfortunately exacerbated by the fact that most compilers don't give literal strings the const qualifier by default.

  9. #9
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: Standard C strings

    Quote Originally Posted by Lindley View Post
    This issue is unfortunately exacerbated by the fact that most compilers don't give literal strings the const qualifier by default.
    They SHOULD....can you provide any examples???

    Also be carefuly about the difference between a literal and a character array INITIALIZED iwht a literal at time of declaration. This gets many people!!
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  10. #10
    Join Date
    Mar 2003
    Location
    India {Mumbai};
    Posts
    3,871

    Re: Standard C strings

    Code:
    strmani(L"my string without buffer\0");
    Just wondering why and which compiler did not issue error for this statement. On Visual C++, it would simply reject the statement by saying, "Cannot covert 'const wchar_t*' to 'wchar_t*'"
    My latest article: Explicating the new C++ standard (C++0x)

    Do rate the posts you find useful.

  11. #11
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Standard C strings

    Quote Originally Posted by Ajay Vijay
    Just wondering why and which compiler did not issue error for this statement. On Visual C++, it would simply reject the statement by saying, "Cannot covert 'const wchar_t*' to 'wchar_t*'"
    The wide string literal L"manipulate me\0" is not of type const wchar_t*, but of type const wchar_t[15]. The conversion from const wchar_t[N] to wchar_t* is allowed, though it is deprecated. I would have expected a warning because of the deprecation, but apparently neither MSVC8 nor the MinGW port of g++ 3.4.5 warn of this even at maximum warning levels.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

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