gpt4 book ai didi

c++ - 在宏内的 if 语句中否定表达式会产生奇怪的结果

转载 作者:行者123 更新时间:2023-12-05 02:35:05 24 4
gpt4 key购买 nike

我遇到了一个有点奇怪的问题。这让我觉得答案非常明显,我只是没有看到任何东西,因为代码太简单了。

我基本上有一个名为“ASSERT”的宏,可确保值不为假。如果是,它会向控制台写入一条消息并中断调试。我的问题是,当断言从 std::string::find_first_of(...) 返回的索引不等于 std::string::npos 时,断言似乎根本不起作用。每次,断言都会失败。

我已经验证了调试中断发生时值不相等,所以我没有看到断言是如何失败的。

在我的原始代码中,它将数据从文件读取到字符串,但问题似乎仍然存在于下面的示例中,除了一个 const std::string。

我正在做一个更大的项目,但这里有一个重现错误的最小示例(顺便说一句,我使用的是 Visual Studio 2022 和 C++17):

#include <iostream>
#include <string>

#define ASSERT(x, msg) {if(!x) { std::cout << "Assertion Failed: " << msg << "\n"; __debugbreak(); } }

int main() {

const std::string source = "Some string that\r\n contains the newline character: \r\n...";

size_t eol = source.find_first_of("\r\n", 0);
ASSERT(eol != std::string::npos, "Newline not present!");

// Other code...

return 0;
}

请注意,即使字符串中只有一个换行符 ("\r\n"),也会发生完全相同的事情。

有趣的是,“eol”似乎在我运行的每个测试用例中都有正确的值。唯一错误的是断言,所以如果我忽略它并继续,一切都会按照我的预期运行。

我也发现了这个似乎相关的问题,但没有得到答案或结论: std::string::find_first_of does not return the expected value

最佳答案

这是预处理器的宏替换引擎设计的简单愚蠢的意想不到的结果。提供给宏的表达式不会像函数那样被求值,文本会在替换过程中直接插入。

给定

#define ASSERT(x, msg) {if(!x) { std::cout << "Assertion Failed: " << msg << "\n"; __debugbreak(); } }

线

ASSERT(eol != std::string::npos, "Newline not present!");

将转化为

{if(!eol != std::string::npos) { std::cout << "Assertion Failed: " << "Newline not present!" << "\n"; __debugbreak(); } }

! 仅应用于 eol,将宏的预期行为更改为无意义的行为。

添加评论中推荐的额外括号

#define ASSERT(x, msg) {if(!(x)) { std::cout << "Assertion Failed: " << msg << "\n"; __debugbreak(); } }

结果

{if(!(eol != std::string::npos)) { std::cout << "Assertion Failed: " << "Newline not present!" << "\n"; __debugbreak(); } }

现在表达式在应用 ! 和测试之前被评估。

因为 macros are "evil" ,并且由于宏不使用任何特殊的、位置相关的调试宏,如 __FILE____LINE__,在这种情况下,我将用函数替换宏并计数关于编译器的优化以内联它。

关于c++ - 在宏内的 if 语句中否定表达式会产生奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70627806/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com