PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, May 12, 2022

[FIXED] Why is appending an int to a std::string undefined behavior with no compiler warning in C++?

 May 12, 2022     append, c++, undefined-behavior, visual-c++, visual-studio     No comments   

Issue

In my code I use logging statements in order to better see what's going on. Sometimes I write code like the following:

int i = 1337;
// More stuff...
logger->info("i has the following value: " + i);

When compiled and executed in debug mode this does not print out i as expected (this is how it would work in Java/C# for example), it rather prints something garbled. In release mode however this might as well crash the entire application. What does the C++ standard say about appending ints to a std::string like I'm doing here?

Why does the compiler not warn me at all when I compile code invoking obvious undefined behavior like this? Am I missing something? I'm using Visual Studio 2022 (MSVC). The correct way to do the logging statement would be converting the int to a std::string explicitly:

logger->info("i has the following value: " + std::to_string(i));

However this bug easily slips through during development. My warning level is set to Level4 (/W4).


Solution

The problem is that in

logger->info("i has the following value: " + i);

you are not working with std::string. You are adding an int to a string literal, ie a const char[] array. The const char[] decays into a const char* pointer in certain contexts. In this case, the int advances that pointer forward by 1337 characters, which is way beyond the end of the string literal, and therefore undefined behavior.

You should get a better compiler that warns you about this, ie:

foo.cc:7:42: warning: offset ‘1337’ outside bounds of constant string [-Warray-bounds]
    7 |     foo("i has the following value: " + i);
      |                                          ^

You can use a std::string literal like this:

#include <string>
using namespace std::literals;

void foo(std::string);

void bla() {
    int i = 1337;
    foo("i has the following value: "s + i);
}

and then you get a "nicer" error that "std::string + int" isn't a thing in C++:

foo.cc:8:40: error: no match for ‘operator+’ (operand types are ‘std::__cxx11::basic_string<char>’ and ‘int’)
    8 |     foo("i has the following value: "s + i);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~
      |         |                                |
      |         std::__cxx11::basic_string<char> int
...
going on for 147 lines

After this, it should be obvious that what you want is this instead:

logger->info("i has the following value: "s + std::to_string(i));

Using std::string literals avoids mistakes like this, because it turns warnings (which your compiler doesn't even give) into hard errors, forcing you to write correct code. So I recommend using the s suffix for all strings.



Answered By - Goswin von Brederlow
Answer Checked By - Marie Seifert (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing