为什么在c++中没有编译器警告的std :: string notection行为?
在我的代码中,我使用记录语句为了更好地查看发生了什么。有时我按以下内容编写代码:
int i = 1337;
// More stuff...
logger->info("i has the following value: " + i);
在调试模式下编译和执行时,这不会按预期打印出i
(例如,这是在Java/c#中工作的方式),它会打印出乱七八糟的东西。但是,在发布模式下,这也可能会使整个应用程序崩溃。 c ++
标准对将int附加到std :: String
的标准说什么?
当我编译代码调用明显的未定义行为时,为什么编译器根本不警告我?我想念什么吗?我正在使用Visual Studio 2022(MSVC)。执行记录语句的正确方法是将int转换为std :: string
显式:
logger->info("i has the following value: " + std::to_string(i));
但是,此错误在开发过程中很容易通过。我的警告级别设置为Level4(/W4)
。
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)
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题在于,
您不使用
std :: String
。您将int
添加到字符串文字中,即const char []
array。const char []
在某些情况下衰减到const char*
指针。在这种情况下,int
将指针以1337个字符向前前进,这超出了字符串字面的末尾,因此不确定的行为。您应该得到一个更好的编译器,以警告您,即:
您可以使用
std :: string
像这样的文字:然后您会遇到一个“ net net new”错误,即“ std :: string + int + int “在C ++中不是一件事情:
之后,应该很明显,您想要的是:
使用
std :: String
文字避免这样的错误,因为它会发出警告(您的编译器)甚至都不会给您的错误错误,迫使您编写正确的代码。因此,我建议使用s
后缀所有字符串。The problem is that in
you are not working with
std::string
. You are adding anint
to a string literal, ie aconst char[]
array. Theconst char[]
decays into aconst char*
pointer in certain contexts. In this case, theint
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:
You can use a
std::string
literal like this:and then you get a "nicer" error that "std::string + int" isn't a thing in C++:
After this, it should be obvious that what you want is this instead:
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 thes
suffix for all strings.这条线是正确的,
在表达式中
,使用指针算术。
例如,如果您要编写
,则该行具有相同的效果,如果要编写
此行
等于行
在表达式中在这里做的一样,没有类型
std :: String
的对象。有一个字符串字面的字符串,它只有一个普通数组类型,该数组类型是带有指针算术的表达式操作数。在表达式中,字符串文字被隐式转换为指针转换为其类型const char *
的第一个元素。This line is correct,
in the expression
there is used the pointer arithmetic.
For example if you will write
then this line has the same effect if to write
That is this line
is equivalent to the line
In the expression there is no object of the type
std::string
. There is used a string literal that has just an ordinary array type that is an operand of an expression with the pointer arithmetic. In the expression the string literal is implicitly converted to a pointer to its first element of the typeconst char *
.