What's the behaviour of “” + number and why c++ compile it?

后端 未结 2 1301
温柔的废话
温柔的废话 2021-01-25 02:48

In the code below i successfully compile it but i can\'t understand why for certain values of number the program crash and for other values it\'s not. Could someone explain the

相关标签:
2条回答
  • 2021-01-25 03:26

    In C++, "" is a const char[1] array, which decays into a const char* pointer to the first element of the array (in this case, the string literal's '\0' nul terminator).

    Adding an integer to a pointer performs pointer arithmetic, which will advance the memory address in the pointer by the specified number of elements of the type the pointer is declared as (in this case, char).

    So, in your example, ... << ("" + number) << ... is equivalent to ... << &""[number] << ..., or more generically:

    const char *ptr = &""[0];
    ptr = reinterpret_cast<const char*>(
        reinterpret_cast<const uintptr_t>(ptr)
        + (number * sizeof(char))
    );
    ... << ptr << ...
    

    Which means you are going out of bounds of the array when number is any value other than 0, thus your code has undefined behavior and anything could happen when operator<< tries to dereference the invalid pointer you give it.

    Unlike in many scripting languages, ("" + number) is not the correct way to convert an integer to a string in C++. You need to use an explicit conversion function instead, such as std::to_string(), eg:

    #include <iostream>
    #include <string>
    
    int main()
    {
        long int number = 255;
        std::cout << "Value 1 : " << std::flush << std::to_string(number) << std::flush << std::endl;
        number = 15155;
        std::cout << "Value 2 : " << std::flush << std::to_string(number) << std::flush << std::endl;
        return 0;
    }
    

    Or, you can simply let std::ostream::operator<< handle that conversion for you, eg:

    #include <iostream>
    
    int main()
    {
        long int number = 255;
        std::cout<< "Value 1 : " << std::flush << number << std::flush << std::endl;
        number = 15155;
        std::cout<< "Value 2 : " << std::flush << number << std::flush << std::endl;
        return 0;
    }
    
    0 讨论(0)
  • 2021-01-25 03:41

    Pointer arithmetic is the culprit.

    A const char* is accepted by operator<<, but will not point to a valid memory address in your example.

    If you switch on -Wall, you will see a compiler warning about that:

    main.cpp: In function 'int main()':
    main.cpp:6:59: warning: array subscript 255 is outside array bounds of 'const char [1]' [-Warray-bounds]
        6 |     std::cout<< "Value 1 : " << std::flush << ("" + number) << std::flush << std::endl;
          |                                                           ^
    main.cpp:8:59: warning: array subscript 15155 is outside array bounds of 'const char [1]' [-Warray-bounds]
        8 |     std::cout<< "Value 2 : " << std::flush << ("" + number) << std::flush << std::endl;
          |                                                           ^
    Value 1 :  q
    

    Live Demo

    0 讨论(0)
提交回复
热议问题