【发布时间】:2022-01-07 22:23:31
【问题描述】:
我遇到了一个有点奇怪的问题。这让我觉得答案非常明显,我只是没有看到任何东西,因为代码太简单了。
我基本上有一个名为“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)) { ... } } -
开启所有编译器警告。该宏应至少生成六个,包括“注意:在左侧表达式周围添加括号以消除此警告”。
-
Visual Studio 对此的警告消息非常可悲。 GCC 更有帮助:godbolt.org/z/nv3Mavcb1 我保留了几个不同的编译器,以查看是否可以看到其他人遗漏的错误,以及 Matt Godbolt 的编译器资源管理器......这是快速比较小段代码结果的炸弹。跨度>
-
请不要删除问题。我已经编辑了标题以更清楚地描述错误,并且更易于搜索。这可能是重复的,但它仍然是一个有用的问题。
-
就像我说的:恰当的问题。任何对此感到困惑的人都需要比我们在这里提供的更多帮助。