简体   繁体   English

调试断言在发布版本中究竟会做什么?

[英]What exactly the debug assert will do in release build?

My application behaves strange in release build when handling Chinese characters(wide). 处理中文字符(宽)时,我的应用程序在发布版本中表现得很奇怪。 I have below line which throw debug assert during debug mode: 我在调试模式期间抛出调试断言的下面一行:

str.erase(std::remove_if(str.begin(), str.end(), isspace), str.end());

(Where str is std::wstring) This line throw the assert when in debug mode. (其中str是std :: wstring)这行在调试模式下抛出断言。 I know this is because isspace cannot handle wide char. 我知道这是因为isspace无法处理宽字符。 Instead of isspace , I have to use iswspace . 而不是isspace ,我必须使用iswspace

str.erase(std::remove_if(str.begin(), str.end(), isspace), str.end());

            if (!str.empty())
            { // add str to GUI }

If I press ' Ignore ' in the debug assert, the str is added to the GUI properly. 如果我在调试断言中按“ 忽略 ”,则str会正确添加到GUI中。 But during release mode, the str is not added to GUI. 但在发布模式下, str不会添加到GUI。

But if I use iswspace , the str is added to the GUI properly without making any change to my add to GUI logic. 但是如果我使用iswspacestr会被正确地添加到GUI中,而不会对我添加到GUI逻辑进行任何更改。

Whats more strange is that some of the Chinese characters are added properly to the GUI during release mode also. 更奇怪的是,在发布模式期间,一些中文字符也被正确地添加到GUI中。 For example, str is added to GUI when it is L"左" . 例如,当它是L“左”时,str被添加到GUI。 But not added to GUI when it is L"右" . 但是当它是L“右”时没有添加到GUI。

Did any one had this issue? 有人有这个问题吗?

My understanding was in release mode, the debug asserts will not be considered and will work similar to ' Ignore '. 我的理解是在发布模式下,调试断言将不会被考虑,并且将类似于“ 忽略 ”。

Edit: 编辑:

I debugged it further(in release). 我进一步调试了它(在发布中)。 Looks like somehow it is not going inside if(!str.empty()) in the case of L"右" . L“右”的情况下,如果(!str.empty())在某种程度上它不会进入内部。 But the visual studio debugger still shows L"右" inside str when it hit the break-point at the if condition. 但是当视觉工作室调试器在if条件下达到断点时仍然在str内显示L“右”。

Edit 2: I added std::locale::global(std::locale("")); 编辑2:我添加了std::locale::global(std::locale("")); above the str.erase line. 在str.erase线上方。 Now it works exactly same in debug and release case and text is added to the GUI. 现在它在调试和发布案例中完全相同,并且文本被添加到GUI。

Here is an example: 这是一个例子:

#include <string>
#include <iostream>
#include <algorithm>

int main(int argc, char* argv[])
{
    std::wstring str1 = L"左";
    std::wstring str2 = L"右";
    str1.erase(std::remove_if(str1.begin(), str1.end(), isspace), str1.end());
    if (!str1.empty())
    {
        std::wcout << L"str1 not empty\n";
    }
    str2.erase(std::remove_if(str2.begin(), str2.end(), isspace), str2.end());
    if (!str2.empty())
    {
        std::wcout << L"str2 not empty\n";
    }
    getchar();
    return 0;
}

This print only "str1 not empty". 此打印仅“str1 not empty”。

Macro assert does nothing in release mode and will be ignored. assert在发布模式下不执行任何操作,将被忽略。

If NDEBUG is defined as a macro name at the point in the source code where is included, then assert does nothing 1 , 2 . 如果NDEBUG是在被包括在源代码中的点定义为宏名称,然后断言不执行任何12

However, just ignoring the assertion doesn't solve the issue. 但是,忽略断言并不能解决问题。 Make your code work in debug mode. 使您的代码在调试模式下工作。

My understanding was in release mode, the debug asserts will not be considered and will work similar to 'Ignore'. 我的理解是在发布模式下,调试断言将不会被考虑,并且将类似于“忽略”。

Yes, but you're ignoring undefined behaviour , because you're passing out-of-range values to isspace . 是的,但是你忽略了未定义的行为 ,因为你将超出范围的值传递给了isspace

Read documentation for the features and functions that you use: 阅读您使用的功能和文档的文档

The behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF . 如果ch的值不能表示为unsigned char且不等于EOF ,则行为未定义。

Really, you should not be using isspace for this. 真的,你不应该为此使用isspace Use a library that supports whatever encoding you're using (UTF-8? UTF-16?) 使用支持您正在使用的任何编码的库(UTF-8?UTF-16?)

Use iswspace (and its wide-char brethren) for wide strings: 使用iswspace (及其宽字符兄弟)来表示宽字符串:

#include <string>
#include <algorithm>
#include <iostream>

int main(int argc, char* argv[])
{
    std::wstring str1 = L"左";
    std::wstring str2 = L"右";
    str1.erase(std::remove_if(str1.begin(), str1.end(), iswspace), str1.end());
    if (!str1.empty())
    {
        std::wcout << L"str1 not empty\n";
    }
    str2.erase(std::remove_if(str2.begin(), str2.end(), iswspace), str2.end());
    if (!str2.empty())
    {
        std::wcout << L"str2 not empty\n";
    }
    getchar();
    return 0;
}

Output: 输出:

str1 not empty
str2 not empty

Whether the isspace version "worked" or did not "work" in release mode or debug mode is a red herring, as you have been invoking undefined behavior : 在发布模式或调试模式下, isspace版本是“工作”还是“工作”是一个红色鲱鱼,因为您一直在调用未定义的行为

CppReference.com on isspace , emphasis mine: 关于isspace的CppReference.com ,强调我的:

The behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF . 如果ch的值不能表示为unsigned char且不等于EOF ,则行为未定义

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM