D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 8765 - assert should print the source code for the condition when no message argument present
Summary: assert should print the source code for the condition when no message argumen...
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: Andrej Mitrovic
URL: https://github.com/D-Programming-Lang...
Keywords: pull
: 8058 (view as issue list)
Depends on:
Blocks:
 
Reported: 2012-10-05 19:59 UTC by Val Markovic
Modified: 2022-09-08 09:36 UTC (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Val Markovic 2012-10-05 19:59:52 UTC
I'd love to see the following:

assert(5 == 4);

print out the actual source code of the condition on failure, that is "core.exception.AssertError@foo.d(123): 5 == 4". This should happen when there is no user-defined message (and maybe _in addition to_ the provided message). Currently I just get "unittest failure" instead of the condition source, which is useless.

This would make it far, far easier to track down which assert failed without having to actually go look at the line number in the file. Also, this is what most unit-testing libraries for other languages do already, like for example GoogleTest for C++ etc.

Since assert() is not a function but an expression in the language, this should not be impossible to implement, should it? GoogleTest does it with macros, but (thank God) we don't have those in D.
Comment 1 Andrej Mitrovic 2012-10-20 16:33:23 UTC
(In reply to comment #0)
> assert(5 == 4);

When there is no message I can change this to:

core.exception.AssertError@test.d(5): assert(5 == 4)

Would this be ok with Walter? It's a 2 line change in the front-end.
Comment 2 Andrej Mitrovic 2012-10-20 16:44:41 UTC
(In reply to comment #1)
> (In reply to comment #0)
> > assert(5 == 4);

Actually wait a minute, it already does this in 2.060. Is there some other example where this doesn't work?
Comment 3 bearophile_hugs 2012-10-21 14:04:36 UTC
(In reply to comment #2)

> Actually wait a minute, it already does this in 2.060. Is there some other
> example where this doesn't work?

If I compile and run this program (Windows):


void main() {
    assert(5 == 4);
}


It gives me:

core.exception.AssertError@test(2): Assertion failure

Followed by a stack trace.
Comment 4 Andrej Mitrovic 2012-10-21 14:07:48 UTC
(In reply to comment #3)
> (In reply to comment #2)
> 
> > Actually wait a minute, it already does this in 2.060. Is there some other
> > example where this doesn't work?
> 
> If I compile and run this program (Windows):
> 
> 
> void main() {
>     assert(5 == 4);
> }
> 
> 
> It gives me:
> 
> core.exception.AssertError@test(2): Assertion failure
> 
> Followed by a stack trace.

OK will fix then.
Comment 5 Val Markovic 2012-10-21 20:52:19 UTC
Same as bearophile; the following program

void main() {
    assert(5 == 4);
}

gives me the following output:

core.exception.AssertError@test(2): Assertion failure
----------------
5   test                                0x000000010d95b05a _d_assertm + 38
6   test                                0x000000010d948df7 void test.__assert(int) + 23
7   test                                0x000000010d948dda _Dmain + 14
8   test                                0x000000010d95b9ae extern (C) int rt.dmain2.main(int, char**).void runMain() + 34
9   test                                0x000000010d95b365 extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void delegate()) + 45
10  test                                0x000000010d95b9f8 extern (C) int rt.dmain2.main(int, char**).void runAll() + 56
11  test                                0x000000010d95b365 extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void delegate()) + 45
12  test                                0x000000010d95b2ef main + 235
13  libdyld.dylib                       0x00007fff89dae7e1 start + 0
14  ???                                 0x0000000000000001 0x0 + 1
----------------

My system/configuration is as follows:

OS: Mac OS X Mountain Lion 10.8
DMD64 v2.060
rdmd build 20120724
command: rdmd -unittest test.d
Comment 6 Andrej Mitrovic 2012-10-22 21:00:45 UTC
*** Issue 8058 has been marked as a duplicate of this issue. ***
Comment 7 Andrej Mitrovic 2013-01-01 15:20:16 UTC
https://github.com/D-Programming-Language/dmd/pull/1426
Comment 8 yebblies 2013-11-24 04:43:09 UTC
Time for a resurrection?
Comment 9 Andrej Mitrovic 2013-11-24 05:18:56 UTC
(In reply to comment #8)
> Time for a resurrection?

Yeah, I'll give it another go soon.
Comment 10 Walter Bright 2014-06-19 17:20:13 UTC
(In reply to bearophile_hugs from comment #3)
> It gives me:
> 
> core.exception.AssertError@test(2): Assertion failure
> 
> Followed by a stack trace.

I don't get it - what's the problem?
Comment 11 Walter Bright 2014-06-19 17:55:35 UTC
(In reply to Val Markovic from comment #0)
> Currently I just get "unittest failure" instead of the condition
> source, which is useless.

It gives the file/line, which is not useless:

1. editors, IDEs, etc., can take you right to the source code of the error

2. assert checks can add a great deal of bloat to the executable - the current implementation tries to minimize that. Adding expression strings to all of them will dramatically increase the size of an executable

I just do not understand why file/line is not sufficient.
Comment 12 Andrej Mitrovic 2015-10-11 15:36:20 UTC
(In reply to Walter Bright from comment #11)
> (In reply to Val Markovic from comment #0)
> > Currently I just get "unittest failure" instead of the condition
> > source, which is useless.
> 
> It gives the file/line, which is not useless:
> 
> 1. editors, IDEs, etc., can take you right to the source code of the error
> 
> 2. assert checks can add a great deal of bloat to the executable - the
> current implementation tries to minimize that. Adding expression strings to
> all of them will dramatically increase the size of an executable
> 
> I just do not understand why file/line is not sufficient.

If the assert is triggered at runtime in a realtime application you want to make sure you get the relevant information back to you as soon as possible. You may not even have the source at hand, it would really help knowing what condition failed.

Code bloat is an issue, but if the requirement is a minimal binary then it would be safe to assume -release is implied, no? So the asserts wouldn't be compiled in anywho.

In any case I'll work on this PR again.
Comment 13 Timothee Cour 2018-02-03 09:32:06 UTC
my PR solves exactly this problem but in a more general way: https://github.com/dlang/dmd/pull/7821
Comment 14 moonlightsentinel 2021-11-05 00:37:11 UTC
Meanwhile `-checkaction=context` exists which will print the failing expression using the actual values instead of the plain source code. Can this be closed?
Comment 15 RazvanN 2022-09-08 09:36:09 UTC
Yes, this has been fixed by: https://github.com/dlang/dmd/pull/8517