www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - assert(false) in release == splinter in eye

reply Christopher Bergqvist <chris digitalpoetry.se> writes:
Hi,

Time for some Sunday nitpicking. While reading TDPL, one thing that stuck
out to me was the special behavior of assert(false). Consider the following
program compiled with "-release".

void main()
{
    int a = 0;
    assert(a);
}

That program will run without errors. Changing the type of variable a from
"int" to "enum" results in the program segfaulting thanks to the compiler
being able to know the value of the expression "a" at compile time and
inserting a HLT/"halt" instruction. Having the ability to change something
subtle in a more complex expression or series of expressions without
realizing you made a compile time assert(false) which crashes your program
feels ugly.

I would prefer it if assert() didn't have this special type of behavior, and
that a "halt" keyword or equivalent was introduced. What do you think?

/ Chris
Oct 10 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Christopher Bergqvist:
 I would prefer it if assert() didn't have this special type of behavior, and
 that a "halt" keyword or equivalent was introduced. What do you think?
A halt() intrinsic from sounds indeed cleaner. But I don't know if Walter is willing to add a keyword just for this purpose. Bye bearophile
Oct 10 2010
parent reply Lutger <lutger.blijdestijn gmail.com> writes:
bearophile wrote:

 Christopher Bergqvist:
 I would prefer it if assert() didn't have this special type of behavior, and
 that a "halt" keyword or equivalent was introduced. What do you think?
A halt() intrinsic from sounds indeed cleaner. But I don't know if Walter is willing to add a keyword just for this purpose. Bye bearophile
assert(halt)? (thinking of scope) I agree btw, this is very error prone.
Oct 11 2010
parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Lutger <lutger.blijdestijn gmail.com> wrote:

 bearophile wrote:

 assert(halt)? (thinking of scope)

 I agree btw, this is very error prone.
Error prone? When should the program haltin debug mode, but not in release? -- Simen
Oct 11 2010
parent Lutger <lutger.blijdestijn gmail.com> writes:
Simen kjaeraas wrote:

 Lutger <lutger.blijdestijn gmail.com> wrote:
 
 bearophile wrote:

 assert(halt)? (thinking of scope)

 I agree btw, this is very error prone.
Error prone? When should the program haltin debug mode, but not in release?
You're right, I wasn't thinking clear.
Oct 11 2010
prev sibling next sibling parent reply Tomek =?UTF-8?B?U293acWEc2tp?= <just ask.me> writes:
Christopher Bergqvist napisał:

 Hi,
 
 Time for some Sunday nitpicking. While reading TDPL, one thing that stuck
 out to me was the special behavior of assert(false). Consider the
 following program compiled with "-release".
 
 void main()
 {
     int a = 0;
     assert(a);
 }
 
 That program will run without errors. Changing the type of variable a from
 "int" to "enum" results in the program segfaulting thanks to the compiler
 being able to know the value of the expression "a" at compile time and
 inserting a HLT/"halt" instruction. Having the ability to change something
 subtle in a more complex expression or series of expressions without
 realizing you made a compile time assert(false) which crashes your program
 feels ugly.

 I would prefer it if assert() didn't have this special type of behavior,
 and that a "halt" keyword or equivalent was introduced. What do you think?
I have the same feeling. 'halt' is good, 'fail' is good too. It doesn't have to be a keyword, a function in object.d would suffice. BTW, does anybody know the reason for the assert(0) infernal syntax? -- Tomek
Oct 10 2010
next sibling parent reply Christopher Bergqvist <chris digitalpoetry.se> writes:
Thanks for the support guys. :)

Unfortunately "halt" would still need to be a keyword if one wants to keep
the full behavior of assert(0), where the compiler knows that it affects th=
e
control-flow of the program.

Legal:
int main()
{
    assert(0);
}

Illegal (Error: function D main has no return statement, but is expected to
return a value of type int):
int main()
{
    int a =3D 0;
    assert(a);
}


2010/10/10 Tomek Sowi=C5=84ski <just ask.me>

 Christopher Bergqvist napisa=C5=82:

 Hi,

 Time for some Sunday nitpicking. While reading TDPL, one thing that stu=
ck
 out to me was the special behavior of assert(false). Consider the
 following program compiled with "-release".

 void main()
 {
     int a =3D 0;
     assert(a);
 }

 That program will run without errors. Changing the type of variable a
from
 "int" to "enum" results in the program segfaulting thanks to the compil=
er
 being able to know the value of the expression "a" at compile time and
 inserting a HLT/"halt" instruction. Having the ability to change
something
 subtle in a more complex expression or series of expressions without
 realizing you made a compile time assert(false) which crashes your
program
 feels ugly.

 I would prefer it if assert() didn't have this special type of behavior=
,
 and that a "halt" keyword or equivalent was introduced. What do you
think? I have the same feeling. 'halt' is good, 'fail' is good too. It doesn't have to be a keyword, a function in object.d would suffice. BTW, does anybody know the reason for the assert(0) infernal syntax? -- Tomek
Oct 10 2010
parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 11 Oct 2010 03:53:07 +0400, Christopher Bergqvist  
<chris digitalpoetry.se> wrote:

 Thanks for the support guys. :)

 Unfortunately "halt" would still need to be a keyword if one wants to  
 keep
 the full behavior of assert(0), where the compiler knows that it affects  
 the
 control-flow of the program.

 Legal:
 int main()
 {
     assert(0);
 }

 Illegal (Error: function D main has no return statement, but is expected  
 to
 return a value of type int):
 int main()
 {
     int a = 0;
     assert(a);
 }
Just a random thought: class Foo { this(int i) { ... } } class Bar { this(int j) { assert(false); } } Still illegal, but that's a bug I guess.
Oct 10 2010
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Tomek S.:

 BTW, does anybody know the reason for the assert(0) infernal syntax?
I think it's a shorcut, to gain a functionality without adopting a specific syntax. An as it very often happens in language design, shortcuts later come back to bite your bum :-) Bye, bearophile
Oct 10 2010
prev sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Mon, 11 Oct 2010 00:22:38 +0300, Tomek Sowiński <just ask.me> wrote:

 BTW, does anybody know the reason for the assert(0) infernal syntax?
From http://www.digitalmars.com/d/2.0/expression.html#AssertExpression: "The expression assert(0) is a special case; it signifies that it is unreachable code. Either AssertError is thrown at runtime if it is reachable, or the execution is halted (on the x86 processor, a HLT instruction can be used to halt execution). The optimization and code generation phases of compilation may assume that it is unreachable code." Sometimes it's useful to add an assert(0) at the end of a function which should always return at other points, but the compiler can't know that. -- Best regards, Vladimir mailto:vladimir thecybershadow.net
Oct 10 2010
prev sibling next sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Christopher Bergqvist Wrote:

 Hi,
 
 Time for some Sunday nitpicking. While reading TDPL, one thing that stuck
 out to me was the special behavior of assert(false). Consider the following
 program compiled with "-release".
-release is misnamed. It should be -unsafe or -unchecked or something like that. Range checking for arrays is also disabled, as are contracts. These are all things that some people actually want turned on in "released" software.
Oct 11 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, October 11, 2010 07:31:54 Sean Kelly wrote:
 Christopher Bergqvist Wrote:
 Hi,
 
 Time for some Sunday nitpicking. While reading TDPL, one thing that stuck
 out to me was the special behavior of assert(false). Consider the
 following program compiled with "-release".
-release is misnamed. It should be -unsafe or -unchecked or something like that. Range checking for arrays is also disabled, as are contracts. These are all things that some people actually want turned on in "released" software.
I thought that bounds checking was supposed to be enabled in release mode unless it was trusted or system. Of course, given that safe, trusted, and system aren't much used at this point (and need work to be properly useable), that would mean that most code now would not have it enabled with -release. What I find worse than -release though is -debug. -debug tends to imply debug mode, which in most people's minds is the opposite of release mode, but -debug just has to do with enabling debug blocks and has no releation to -release. So, both -release and -debug cause at least some level of confusion. - Jonathan M Davis
Oct 11 2010
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 10 Oct 2010 19:52:28 +0400, Christopher Bergqvist  
<chris digitalpoetry.se> wrote:

 Hi,

 Time for some Sunday nitpicking. While reading TDPL, one thing that stuck
 out to me was the special behavior of assert(false). Consider the  
 following
 program compiled with "-release".

 void main()
 {
     int a = 0;
     assert(a);
 }

 That program will run without errors. Changing the type of variable a  
 from
 "int" to "enum" results in the program segfaulting thanks to the compiler
 being able to know the value of the expression "a" at compile time and
 inserting a HLT/"halt" instruction. Having the ability to change  
 something
 subtle in a more complex expression or series of expressions without
 realizing you made a compile time assert(false) which crashes your  
 program
 feels ugly.

 I would prefer it if assert() didn't have this special type of behavior,  
 and
 that a "halt" keyword or equivalent was introduced. What do you think?

 / Chris
There is a C abort() function, and most compiler recognize that it doesn't return.
Oct 11 2010
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/10/2010 10:52 AM, Christopher Bergqvist wrote:
 Hi,

 Time for some Sunday nitpicking. While reading TDPL, one thing that
 stuck out to me was the special behavior of assert(false). Consider the
 following program compiled with "-release".

 void main()
 {
      int a = 0;
      assert(a);
 }

 That program will run without errors. Changing the type of variable a
 from "int" to "enum" results in the program segfaulting thanks to the
 compiler being able to know the value of the expression "a" at compile
 time and inserting a HLT/"halt" instruction. Having the ability to
 change something subtle in a more complex expression or series of
 expressions without realizing you made a compile time assert(false)
 which crashes your program feels ugly.

 I would prefer it if assert() didn't have this special type of behavior,
 and that a "halt" keyword or equivalent was introduced. What do you think?

 / Chris
I followed this thread. assert(false) is clearly an unpleasant irregularity in the language. In the beginning I was really bothered by it but with time I have to admit it's not a big deal in practice. assert(false) could be in an ideal world replaced by an intrinsic called e.g. halt() that looks and feels like a regular function but is recognized by the compiler. No new keyword would be needed. But I don't think that would mark a significant improvement in the language. Andrei
Oct 11 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei:

 assert(false) could be in an ideal world replaced by an intrinsic called 
 e.g. halt() that looks and feels like a regular function but is 
 recognized by the compiler. No new keyword would be needed. But I don't 
 think that would mark a significant improvement in the language.
I'd like the halt() intrinsic :-) Its main disadvantages are that you need to import it from the intrinsics core module, that you break a bit more backwards compatibility with D1 (because once halt() is present, then assert(0); must vanish in release mode). Bye, bearophile
Oct 11 2010
parent reply Christopher Bergqvist <chris digitalpoetry.se> writes:
On Tue, Oct 12, 2010 at 2:37 AM, Andrei Alexandrescu <
SeeWebsiteForEmail erdani.org> wrote:

 assert(false) could be in an ideal world replaced by an intrinsic called
 e.g. halt() that looks and feels like a regular function but is recognized
 by the compiler. No new keyword would be needed. But I don't think that
 would mark a significant improvement in the language.
Would it be possible to change the compiler to only treat "assert(false);" specially, avoiding treating "enum a = 0; assert(a);" or more complex constructs that way?
Oct 12 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/12/10 13:58 CDT, Christopher Bergqvist wrote:
 On Tue, Oct 12, 2010 at 2:37 AM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org
 <mailto:SeeWebsiteForEmail erdani.org>> wrote:

     assert(false) could be in an ideal world replaced by an intrinsic
     called e.g. halt() that looks and feels like a regular function but
     is recognized by the compiler. No new keyword would be needed. But I
     don't think that would mark a significant improvement in the language.


 Would it be possible to change the compiler to only treat
 "assert(false);" specially, avoiding treating "enum a = 0; assert(a);"
 or more complex constructs that way?
Question is when to stop. assert(0), assert(false), assert(1 == 0)... Andrei
Oct 12 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, October 12, 2010 13:40:32 Andrei Alexandrescu wrote:
 On 10/12/10 13:58 CDT, Christopher Bergqvist wrote:
 On Tue, Oct 12, 2010 at 2:37 AM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org
 
 <mailto:SeeWebsiteForEmail erdani.org>> wrote:
     assert(false) could be in an ideal world replaced by an intrinsic
     called e.g. halt() that looks and feels like a regular function but
     is recognized by the compiler. No new keyword would be needed. But I
     don't think that would mark a significant improvement in the
     language.
 
 Would it be possible to change the compiler to only treat
 "assert(false);" specially, avoiding treating "enum a = 0; assert(a);"
 or more complex constructs that way?
Question is when to stop. assert(0), assert(false), assert(1 == 0)... Andrei
If we were to make that change, I'd say to make it simple and just use assert(0) and assert(false), but it's certainly a valid point. Personally, I don't think that it's an issue because it's really only going to happpen with compile-time constants which wouldn't normally be in an assert statement anyway. - Jonathan M Davis
Oct 12 2010