locked
Unexpected output from string concatenation. RRS feed

  • Question

  • I added the following code to my program.

    string str;

    str="00."+'0';

    The '0' part was converted to a decimal number then added to str giving 00.48

    I would have expected to get str="00.0".

    In C# I do get 00.0.

    Yes  I know I could use "00."+"0" but the compiler should have added strings or thrown up an error.


    n.Wright



    Wednesday, February 19, 2020 2:05 PM

All replies

  • It's the sort of thing a static analyzer might pick up.

    For example, PVS Studio reports:

    V594 The '"00." + '0'' pointer steps out of array's bounds.
    V643 Unusual pointer arithmetic: "00." + '0'. The value of the 'char' type is being added to the string pointer. 

    Wednesday, February 19, 2020 3:09 PM
  • Are you sure this produced "00.48"? Might be some kind of C++/CLI thing.

    In straight C++, this code exhibits undefined behavior. It takes a pointer to string literal "00.0", advances it by 48 bytes, and attempts to interpret that address as a pointer to a nul-terminated string, reading whatever random content happens to be located in memory beyond that string literal.

    This should work:

    str = std::string("00.")+'0';
    // or
    str = "00."
    str += '0';
    


    Igor Tandetnik

    Wednesday, February 19, 2020 10:19 PM
  • There is more to your question than what you are telling us, because what you have said there is completely false.  Under no circumstances will C or C++ automatically convert an integer to its string equivalent.

    Show us the EXACT code you used, and we can explain where you went wrong.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Thursday, February 20, 2020 4:23 AM
  • There is more to your question than what you are telling us, because what you have said there is completely false.  Under no circumstances will C or C++ automatically convert an integer to its string equivalent.

    Show us the EXACT code you used, and we can explain where you went wrong.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Using Visual Studio and C++ I get the result I said"00.48"

    Using VS and C# I get "00.0" which is what I expected. Just adding athe char 0 to a string.

    If you dont believe me try it yourself in VS.


    n.Wright

    Thursday, February 20, 2020 5:39 AM
  • I tried it myself with a VC compiler, and I don't get the results you claim to get: https://rextester.com/FWY89137

    Igor Tandetnik

    Thursday, February 20, 2020 5:50 AM
  • I tried it myself with a VC compiler, and I don't get the results you claim to get: https://rextester.com/FWY89137

    Igor Tandetnik

    You need to use Visua S tudio 2019 to get same results.


    n.Wright

    Thursday, February 20, 2020 6:42 AM
  • C# is not C/C++.

    You try to concate a string literal with a single-character literal. This is not allowed.

    "00." is a pointer to a const character array of size 4.  So '0' will be converted to an int ('0' is the ASCII value 48) to use pointer arithmetics. So it's impossible to concatenate string literals with + .

    You must convert the string literal to std::string first, then the std::string-operator+(char) will be used internally.

    For example:

    std::string s;
    s = std::string("00.") + '0';

    Regards, Guido

    Edit: Pointer arithmetic: https://www.tutorialspoint.com/cprogramming/c_pointer_arithmetic.htm

    So let's say address is 1000, + 48 = 1048. So the pointer points to somewhere else. But as it originally pointed to a string literal, it is forbidden to add a value to the pointer.

    • Edited by Guido Franzke Thursday, February 20, 2020 7:50 AM link added
    Thursday, February 20, 2020 7:24 AM
  • So let's say address is 1000, + 48 = 1048. So the pointer points to somewhere else. But as it originally pointed to a string literal, it is forbidden to add a value to the pointer.

    You can perform pointer arithmetic as long as the resulting address still points within the string or one byte past the end of the string.
    Thursday, February 20, 2020 1:31 PM
  • C# is not C/C++.

    You try to concate a string literal with a single-character literal. This is not allowed.

    "00." is a pointer to a const character array of size 4.  So '0' will be converted to an int ('0' is the ASCII value 48) to use pointer arithmetics. So it's impossible to concatenate string literals with + .

    You must convert the string literal to std::string first, then the std::string-operator+(char) will be used internally.

    For example:

    std::string s;
    s = std::string("00.") + '0';

    Regards, Guido

    Edit: Pointer arithmetic: https://www.tutorialspoint.com/cprogramming/c_pointer_arithmetic.htm

    So let's say address is 1000, + 48 = 1048. So the pointer points to somewhere else. But as it originally pointed to a string literal, it is forbidden to add a value to the pointer.

    I think you are getting confused between pointers and actual strings.

    str=str+"0"; would add 0 to end of string, it wouldn't affect a pointer.

    str=str+'0' should do the same thing (Visual Studio C#) or return an error

    str isn't a pointer it is a string.


    n.Wright

    Thursday, February 20, 2020 1:35 PM

  • So let's say address is 1000, + 48 = 1048. So the pointer points to somewhere else. But as it originally pointed to a string literal, it is forbidden to add a value to the pointer.

    I think you are getting confused between pointers and actual strings.

    str=str+"0"; would add 0 to end of string, it wouldn't affect a pointer.

    str=str+'0' should do the same thing (Visual Studio C#) or return an error

    str isn't a pointer it is a string.


    n.Wright

    Be aware that str = str + "0"   is not the same as str = "00." + "0"

    str=str+"0": you are using the operator+(const char*) of std::string. str is a std::string, not a literal string.

    str = "00." + "0": "00." is NOT a std::string. It is a string literal. A string literal is represented by a pointer. So the + means pointer arithmetics. And this is forbidden.

    Regards, Guido

    Thursday, February 20, 2020 1:57 PM
  • So let's say address is 1000, + 48 = 1048. So the pointer points to somewhere else. But as it originally pointed to a string literal, it is forbidden to add a value to the pointer.

    You can perform pointer arithmetic as long as the resulting address still points within the string or one byte past the end of the string.

    You can perform pointer arithmetics however you want. Only if you run out of the original memory block, then the pointer points to something else. Using such a pointer means, that the programme could crash or other unexpected results occur.

    Regards, Guido

    Thursday, February 20, 2020 2:00 PM
  • So let's say address is 1000, + 48 = 1048. So the pointer points to somewhere else. But as it originally pointed to a string literal, it is forbidden to add a value to the pointer.

    You can perform pointer arithmetic as long as the resulting address still points within the string or one byte past the end of the string.

    You can perform pointer arithmetics however you want. Only if you run out of the original memory block, then the pointer points to something else. Using such a pointer means, that the programme could crash or other unexpected results occur.

    Regards, Guido

    I think the confusion is coming about because Visual Studio C++ also does none standard strings too which is what I am using.

    In this case I can do:

    String^ str="";

    str= "abc"+"def" and get "abcdef"

    When it sees a single quoted character it converts it to a decimal string and adds it to str string, rightly or wrongly.

    Standard strings use pointers.


    n.Wright

    Thursday, February 20, 2020 2:06 PM

  • I think the confusion is coming about because Visual Studio C++ also does none standard strings too which is what I am using.

    In this case I can do:

    String^ str="";

    str= "abc"+"def" and get "abcdef"

    When it sees a single quoted character it converts it to a decimal string and adds it to str string, rightly or wrongly.


    Ok, but String^ is not standard C/C++, it is C++/CLI and is a string class of this programming language.

    It is a different programming language.

    Regards, Guido

    Thursday, February 20, 2020 2:26 PM

  • I think the confusion is coming about because Visual Studio C++ also does none standard strings too which is what I am using.


    When it sees a single quoted character it converts it to a decimal string and adds it to str string, rightly or wrongly.


    A char literal in C++ is not the same as a Char literal in C#.

    If you do this:

    str = "00." + (System::Char)'0';

    you will get 00.0 as in C#.

    - Wayne

    Thursday, February 20, 2020 2:52 PM
  • Note that '0' is a narrow char literal in C++. If you use a wide char literal 
    you will get 00.0 as expected:

    str = "00." + L'0';
    

    - Wayne

    Thursday, February 20, 2020 6:41 PM