在断言中添加自定义消息?
有没有办法添加或编辑断言抛出的消息?我想使用类似的东西
assert(a == b, "A must be equal to B");
然后,编译器添加行,时间等等......
这可能吗?
Is there a way to add or edit the message thrown by assert? I'd like to use something like
assert(a == b, "A must be equal to B");
Then, the compiler adds line, time and so on...
Is it possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我见过的一个技巧是使用
&&
运算符。由于指针如果非空则“为真”,因此您可以在不更改条件的情况下执行以下操作:由于
assert
显示失败的条件,因此它也会显示您的消息。如果这还不够,您可以编写自己的myAssert
函数或宏来显示您想要的任何内容。A hack I've seen around is to use the
&&
operator. Since a pointer "is true" if it's non-null, you can do the following without altering the condition:Since
assert
shows the condition that failed, it will display your message too. If it's not enough, you can write your ownmyAssert
function or macro that will display whatever you want.另一种选择是反转操作数并使用逗号运算符。您需要额外的括号,以便逗号不会被视为参数之间的分隔符:(
这是从上面的注释复制的,以获得更好的可见性)
Another option is to reverse the operands and use the comma operator. You need extra parentheses so the comma isn't treated as a delimiter between the arguments:
(this was copied from above comments, for better visibility)
这是我的断言宏版本,它接受消息并以清晰的方式打印出所有内容:
现在,您可以使用它
,如果失败,您将收到如下消息:
漂亮干净,请随意在代码中使用它 =)
Here's my version of assert macro, which accepts the message and prints everything out in a clear way:
Now, you can use this
And in case of failure you will get a message like this:
Nice and clean, feel free to use it in your code =)
http://www.boost.org/doc/libs/1_51_0/libs/utility/ assert.html
您可以直接使用它或复制 Boost 的代码。另请注意,Boost 断言只是标头,因此如果您不想安装所有 Boost,则可以只获取该单个文件。
http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
You could either use that directly or copy Boost's code. Also note Boost assert is header only, so you could just grab that single file if you didn't want to install all of Boost.
由于 zneak 的答案使代码有些复杂,更好的方法是仅注释您正在谈论的字符串文本。即:
由于断言错误的读者无论如何都会从错误消息中查找文件和行,因此他们将在此处看到完整的解释。
因为,归根结底,
,这:比这更好读
就人类对代码的解析而言 。可读性。也不是语言黑客。
As zneak's answer convolutes the code somewhat, a better approach is to merely comment the string text you're talking about. ie.:
Since the reader of the assert error will look up the file and line anyway from the error message, they will see the full explanation here.
Because, at the end of the day, this:
reads better than this:
in terms of human parsing of code ie. readability. Also not a language hack.
断言是宏/函数的组合。您可以使用
__FILE__
、__BASE_FILE__
、__LINE__
等定义您自己的宏/函数,以及您自己的带有自定义消息的函数assert is a macro/function combination. you can define your own macro/function, using
__FILE__
,__BASE_FILE__
,__LINE__
etc, with your own function that takes a custom message如果断言是在类中完成的,则另一种方法是使用自描述名称调用静态谓词函数。如果断言失败,消息将已经包含谓词的漂亮且自描述的名称。
例如:
您甚至可能希望将该谓词函数公开,以便类的用户可以自己验证前提条件。
即使在发布版本中未禁用
assert
,编译器也可能会内联谓词(如果它相当简单)。相同的方法可用于需要注释的复杂
if
条件。无需注释,只需调用自描述谓词函数即可。If the assert is done within a class, an alternative approach is to call a static predicate function with a self-describing name. If the assertion fails, the message will already contain the predicate's pretty and self-describing name.
E.g.:
You may even want to make that predicate function public so that the class' user can verify the precondition themselves.
Even if
assert
is not disabled for release builds, the compiler will likely inline the predicate if it's fairly trivial.The same approach can be used for complex
if
conditions needing a comment. Instead of a comment, just call a self-describing predicate function.您也可以编写自己的自定义断言函数。一个非常简单的示例:
玩代码。
断言读取
Assertion print_if_false(i == j,“i 和 j 应该相等”)
。You could also just write your own custom assert function. A very simple example:
play with the code.
The assertion reads
Assertion print_if_false(i == j, "i and j should be equal")
.选项 1)由于 fprintf 返回打印的字符数,因此我们可以使用 !fprintf 或断言表达式。此处使用 stderr,因为这是一条错误消息
我们可以将其包装在宏中以方便使用。
选项 2) 定义包含在 lambda 内的错误消息。
这是转储的消息。
选项 3) 或者我们可以改进上述解决方案,借助立即调用的 lambda 在一行中完成此操作
Option 1) Since fprintf returns number of characters printed so we can or assert expression with !fprintf. Using stderr here since this is an error message
We can wrap this inside a macro for convinient use.
Option 2) Define error message wrapped inside lambda.
Here is the dumped message.
Option 3) Or we can refine above solution to do it in one line with help of immediately invoked lambda
@Shakti Malik,非常感谢您的解决方案!
我已将其简化为:
优秀作品)
@Shakti Malik, thank you very much for your solution!
I have reduced it to:
Excellent works)
对于vc,在assert.h中添加以下代码,
For vc, add following code in assert.h,