Topic: Re-define assert() to help the optimizer
Author: =?UTF-8?Q?Fr=C3=A9d=C3=A9ric_TERRAZZONI?= <akryus@gmail.com>
Date: Tue, 27 Nov 2012 12:26:43 -0800 (PST)
Raw View
------=_Part_234_17101209.1354048003600
Content-Type: text/plain; charset=ISO-8859-1
The assert() macro is a very useful tool to document invariants that are
supposed to be true at a certain point in the code. Moreover, they also
help the programmer to find bugs since it is expanded to an error-checking
code in debug mode. However, in release mode (NDEBUG), this macro is
expanded to ((void)0). For me, that specific definition of assert leads to
a loss a useful information that could be used by the optimizer.
For instance, if the optimizer was assert-aware, it would be almost
possible to emulate the restrict keyword of C99 :
void fn_c99(double * restrict a, double * restrict b) { ... }
void fn_cpp(double * a, double * b) { assert(a!=b); ... } // (note: for
equivalence, a & b must not be arrays)
This is only one example, but we can easily imagine more situations where
it could be useful to explicit various constraints (inequalities,
!=nullptr, ...) that would help the optimizer (to remove useless branches
for instance).
By expliciting all the contraints that we have on the variables:
1- We're giving new hints to the optimizer that it cannot prove itself (in
release mode)
2- We can check the conformance of our code to these assertions (in debug
mode)
The current definition of assert() doesn't allow this kind of optimization
since the compiler doesn't even see the assertions (they are removed by the
pre-compiler if NDEBUG is defined). Two little modifications of the
standard would be enough to enable it: let the expansion of assert() be
implementation-defined in release mode + allow assert-based optimizations.
What do you think about this proposal?
--
------=_Part_234_17101209.1354048003600
Content-Type: text/html; charset=ISO-8859-1
<p class="MsoNormal">The assert() macro is a very useful tool to document
invariants that are supposed to be true at a certain point in the code.
Moreover, they also help the programmer to find bugs since it is expanded to an
error-checking code in debug mode. However, in release mode (NDEBUG), this
macro is expanded to ((void)0). For me, that specific definition of assert
leads to a loss a useful information that could be used by the optimizer. <o:p></o:p></p>
<p class="MsoNormal"><br></p>
<p class="MsoNormal">For instance, if the optimizer was assert-aware, it would be almost possible to emulate the restrict keyword of C99 :</p>
<p class="MsoNormal">void fn_c99(double * restrict a, double * restrict b) { ...
} <o:p></o:p></p>
<p class="MsoNormal">void fn_cpp(double * a, double * b) { assert(a!=b); ...
} <o:p></o:p>// (note: for equivalence, a & b must not be arrays)</p>
<p class="MsoNormal"><br></p>
<p class="MsoNormal">This is only one example, but we can easily imagine more
situations where it could be useful to explicit various constraints
(inequalities, !=nullptr, ...) that would help the optimizer (to remove useless branches for instance).</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">By expliciting all the contraints that we have on the variables:<o:p></o:p></p>
<p class="MsoNormal">1- We're giving new hints to the optimizer that it cannot
prove itself (in release mode)<o:p></o:p></p>
<p class="MsoNormal">2- We can check the conformance of our code to these assertions (in debug mode)</p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The current definition of assert() doesn't allow this kind
of optimization since the compiler doesn't even see the assertions (they are removed by the pre-compiler if NDEBUG is defined). Two little modifications of the standard would be enough to enable it:
let the expansion of assert() be implementation-defined in release mode + allow assert-based optimizations.</p><p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"><br></p>
<p class="MsoNormal">What do you think about this proposal?<o:p></o:p></p>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_234_17101209.1354048003600--
.
Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Tue, 27 Nov 2012 21:31:58 +0100
Raw View
--e89a8ff1c85c42bdc204cf7ff2aa
Content-Type: text/plain; charset=ISO-8859-1
The compiler can still see the assertions. The standard does not require
the preprocessor to be separate from the compiler, nor does it forbid the
preprocessor from passing extra information to the compiler. Thus this
optimization is already enabled. If it does not exist in the wild that is
not because of the C++ standard.
Martinho
--
--e89a8ff1c85c42bdc204cf7ff2aa
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
The compiler can still see the assertions. The standard does not require th=
e preprocessor to be separate from the compiler, nor does it forbid the pre=
processor from passing extra information to the compiler. Thus this optimiz=
ation is already enabled. If it does not exist in the wild that is not beca=
use of the C++ standard.<br>
<br clear=3D"all">Martinho<br>
<p></p>
-- <br />
<br />
<br />
<br />
--e89a8ff1c85c42bdc204cf7ff2aa--
.
Author: =?UTF-8?Q?Fr=C3=A9d=C3=A9ric_TERRAZZONI?= <akryus@gmail.com>
Date: Tue, 27 Nov 2012 12:49:19 -0800 (PST)
Raw View
------=_Part_76_26256489.1354049359179
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
The assert() in release mode is defined to be a no-op. As far as I know,=20
the compiler is only allowed to make optimizations if the output preserves=
=20
the semantic.=20
#define NDEBUG
#include <cassert>
int fn(int a) {
assert(a=3D=3D2);
return a*2;
}
In this code, assert() is required by the standard to expand to nop. Here=
=20
the assert() 's semantic is "do nothing", because NDEBUG is defined. So I=
=20
could perfectly call fn(3) and expect it to return 6. Consequently, fn=20
is equivalent to its non-optimized version :
int fn(int a) {
return a*2;
}
My proposal is to slightly change the semantic of assert() in order to=20
allow this kind of optimization.
Le mardi 27 novembre 2012 21:31:58 UTC+1, R. Martinho Fernandes a =E9crit :
>
> The compiler can still see the assertions. The standard does not require=
=20
> the preprocessor to be separate from the compiler, nor does it forbid the=
=20
> preprocessor from passing extra information to the compiler. Thus this=20
> optimization is already enabled. If it does not exist in the wild that is=
=20
> not because of the C++ standard.
>
> Martinho
>
--=20
------=_Part_76_26256489.1354049359179
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div>The assert() in release mode is defined to be a no-op. As far as I kno=
w, the compiler is only allowed to make optimizations if the output preserv=
es the semantic. </div><div><br></div><div>#define NDEBUG</div><div>#i=
nclude <cassert></div><div><br></div><div>int fn(int a) {</div><div><=
span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>assert(a=3D=
=3D2);</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> =
</span>return a*2;</div><div>}</div><div><br></div><div>In this code, asser=
t() is required by the standard to expand to nop. Here the assert() 's sema=
ntic is "do nothing", because NDEBUG is defined. So I could perfectly call =
fn(3) and expect it to return 6. Consequently, fn is equivalent to its=
non-optimized version :</div><div><br></div><div>int fn(int a) {</div><div=
><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>return a*=
2;</div><div>}</div><div><br></div><div>My proposal is to slightly change t=
he semantic of assert() in order to allow this kind of optimization.</div><=
div><br></div><br>Le mardi 27 novembre 2012 21:31:58 UTC+1, R. Martinho Fer=
nandes a =E9crit :<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The com=
piler can still see the assertions. The standard does not require the prepr=
ocessor to be separate from the compiler, nor does it forbid the preprocess=
or from passing extra information to the compiler. Thus this optimization i=
s already enabled. If it does not exist in the wild that is not because of =
the C++ standard.<br>
<br clear=3D"all">Martinho<br>
</blockquote>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_76_26256489.1354049359179--
.
Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Tue, 27 Nov 2012 21:55:35 +0100
Raw View
--e89a8ffba8a3ae4a0a04cf8046d0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On Tue, Nov 27, 2012 at 9:49 PM, Fr=E9d=E9ric TERRAZZONI <akryus@gmail.com>=
wrote:
> The assert() in release mode is defined to be a no-op. As far as I know,
> the compiler is only allowed to make optimizations if the output preserve=
s
> the semantic.
>
> #define NDEBUG
> #include <cassert>
>
> int fn(int a) {
> assert(a=3D=3D2);
> return a*2;
> }
>
> In this code, assert() is required by the standard to expand to nop. Here
> the assert() 's semantic is "do nothing", because NDEBUG is defined. So I
> could perfectly call fn(3) and expect it to return 6. Consequently, fn
> is equivalent to its non-optimized version :
>
> int fn(int a) {
> return a*2;
> }
>
> My proposal is to slightly change the semantic of assert() in order to
> allow this kind of optimization.
>
>
It's a breaking change, then?
Martinho
--=20
--e89a8ffba8a3ae4a0a04cf8046d0
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On Tue, Nov 27, 2012 at 9:49 PM, Fr=E9d=E9ric TERRAZZONI <span dir=3D"ltr">=
<<a href=3D"mailto:akryus@gmail.com" target=3D"_blank">akryus@gmail.com<=
/a>></span> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex">
<div>The assert() in release mode is defined to be a no-op. As far as I kno=
w, the compiler is only allowed to make optimizations if the output preserv=
es the semantic.=A0</div><div><br></div><div>#define NDEBUG</div><div>#incl=
ude <cassert></div>
<div><br></div><div>int fn(int a) {</div><div><span style=3D"white-space:pr=
e-wrap"> </span>assert(a=3D=3D2);</div><div><span style=3D"white-space:pre-=
wrap"> </span>return a*2;</div><div>}</div><div><br></div><div>In this code=
, assert() is required by the standard to expand to nop. Here the assert() =
's semantic is "do nothing", because NDEBUG is defined. So I =
could perfectly call fn(3) and expect it to return 6. Consequently, fn is=
=A0equivalent to its non-optimized version :</div>
<div><br></div><div>int fn(int a) {</div><div><span style=3D"white-space:pr=
e-wrap"> </span>return a*2;</div><div>}</div><div><br></div><div>My proposa=
l is to slightly change the semantic of assert() in order to allow this kin=
d of optimization.</div>
<div><br></div></blockquote></div><br>It's a breaking change, then?<br>=
<br clear=3D"all">Martinho<br>
<br><br>
<p></p>
-- <br />
<br />
<br />
<br />
--e89a8ffba8a3ae4a0a04cf8046d0--
.
Author: =?UTF-8?Q?Fr=C3=A9d=C3=A9ric_TERRAZZONI?= <akryus@gmail.com>
Date: Tue, 27 Nov 2012 13:01:00 -0800 (PST)
Raw View
------=_Part_295_23684414.1354050060880
Content-Type: text/plain; charset=ISO-8859-1
If some assert() doesn't always hold true in a program, then I consider the
code to be already broken. In that sense, it's not a breaking change.
--
------=_Part_295_23684414.1354050060880
Content-Type: text/html; charset=ISO-8859-1
If some assert() doesn't always hold true in a program, then I consider the code to be already broken. In that sense, it's not a breaking change.
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_295_23684414.1354050060880--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 28 Nov 2012 04:15:39 -0800 (PST)
Raw View
------=_Part_115_28138020.1354104940049
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu wtorek, 27 listopada 2012 21:26:43 UTC+1 u=BFytkownik Fr=E9d=E9ric=
=20
TERRAZZONI napisa=B3:
>
> The assert() macro is a very useful tool to document invariants that are=
=20
> supposed to be true at a certain point in the code. Moreover, they also=
=20
> help the programmer to find bugs since it is expanded to an error-checkin=
g=20
> code in debug mode. However, in release mode (NDEBUG), this macro is=20
> expanded to ((void)0). For me, that specific definition of assert leads t=
o=20
> a loss a useful information that could be used by the optimizer.=20
>
>
> For instance, if the optimizer was assert-aware, it would be almost=20
> possible to emulate the restrict keyword of C99 :
>
> void fn_c99(double * restrict a, double * restrict b) { ... } =20
>
> void fn_cpp(double * a, double * b) { assert(a!=3Db); ... } // (note: for=
=20
> equivalence, a & b must not be arrays)
>
>
> This is only one example, but we can easily imagine more situations where=
=20
> it could be useful to explicit various constraints (inequalities,=20
> !=3Dnullptr, ...) that would help the optimizer (to remove useless branch=
es=20
> for instance).
>
> =20
>
> By expliciting all the contraints that we have on the variables:
>
> 1- We're giving new hints to the optimizer that it cannot prove itself (i=
n=20
> release mode)
>
> 2- We can check the conformance of our code to these assertions (in debug=
=20
> mode)
>
> =20
>
> The current definition of assert() doesn't allow this kind of optimizatio=
n=20
> since the compiler doesn't even see the assertions (they are removed by t=
he=20
> pre-compiler if NDEBUG is defined). Two little modifications of the=20
> standard would be enough to enable it: let the expansion of assert() be=
=20
> implementation-defined in release mode + allow assert-based optimizations=
..
>
>
> What do you think about this proposal?
>
I find such proposal very useful. It would enable some assert-based=20
optimizations. This suggestion was raised years ago by Niklas Matthies (see=
=20
here <https://groups.google.com/d/msg/comp.std.c++/L95zvmMXN3I/4SlPwAAUV3MJ=
>).=20
It requires that there is some intrinsic function that represents an=20
undefined behavior that the compiler is aware of:
constexpr bool undefined_behavior() noexcept;
When compiler sees it, it is *guaranteed* that the function will trigger an=
=20
undefined behavior and compiler is allowed to perform arbitrary=20
optimizations (this is a consequence of mixing UB and as-if rules).
Now an assert can be defined as:
#ifdef NDEBUG
# define ASSERT( PRED ) static_cast<void>( (PRED) || undefined_behavior()=
=20
) #endif
This is an information to the compiler: either the condition is true, or=20
you can do whatever you want. I tried to provide a more thorough=20
explanation of the mechanism here<http://akrzemi1.wordpress.com/2011/04/06/=
assertions/#optimization>
..
--=20
------=_Part_115_28138020.1354104940049
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu wtorek, 27 listopada 2012 21:26:43 UTC+1 u=BFytkownik Fr=E9d=
=E9ric TERRAZZONI napisa=B3:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p=
class=3D"MsoNormal">The assert() macro is a very useful tool to document
invariants that are supposed to be true at a certain point in the code.
Moreover, they also help the programmer to find bugs since it is expanded t=
o an
error-checking code in debug mode. However, in release mode (NDEBUG), this
macro is expanded to ((void)0). For me, that specific definition of assert
leads to a loss a useful information that could be used by the optimizer. <=
/p>
<p class=3D"MsoNormal"><br></p>
<p class=3D"MsoNormal">For instance, if the optimizer was assert-aware, it =
would be almost possible to emulate the restrict keyword of C99 :</p>
<p class=3D"MsoNormal">void fn_c99(double * restrict a, double * restrict b=
) { ...
} </p>
<p class=3D"MsoNormal">void fn_cpp(double * a, double * b) { assert(a!=3Db)=
; ...
} // (note: for equivalence, a & b must not be arrays)</p>
<p class=3D"MsoNormal"><br></p>
<p class=3D"MsoNormal">This is only one example, but we can easily imagine =
more
situations where it could be useful to explicit various constraints
(inequalities, !=3Dnullptr, ...) that would help the optimizer (to remove u=
seless branches for instance).</p>
<p class=3D"MsoNormal"> </p>
<p class=3D"MsoNormal">By expliciting all the contraints that we have on th=
e variables:</p>
<p class=3D"MsoNormal">1- We're giving new hints to the optimizer that it c=
annot
prove itself (in release mode)</p>
<p class=3D"MsoNormal">2- We can check the conformance of our code to these=
assertions (in debug mode)</p><p class=3D"MsoNormal"></p>
<p class=3D"MsoNormal"> </p>
<p class=3D"MsoNormal">The current definition of assert() doesn't allow thi=
s kind
of optimization since the compiler doesn't even see the assertions (th=
ey are removed by the pre-compiler if NDEBUG is defined). Two little modifi=
cations of the standard would be enough to enable it:
let the expansion of assert() be implementation-defined in release mode + a=
llow assert-based optimizations.</p><p class=3D"MsoNormal"></p>
<p class=3D"MsoNormal"><br></p>
<p class=3D"MsoNormal">What do you think about this proposal?</p></blockquo=
te><div><br>I find such proposal very useful. It would enable some assert-b=
ased optimizations. This suggestion was raised years ago by Niklas Matthies=
(<a href=3D"https://groups.google.com/d/msg/comp.std.c++/L95zvmMXN3I/4SlPw=
AAUV3MJ">see here</a>). It requires that there is some intrinsic function t=
hat represents an undefined behavior that the compiler is aware of:<br><br>=
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); b=
order-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wo=
rd-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> undefined_behavior</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> noexcept</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br>Whe=
n compiler sees it, it is <u>guaranteed</u> that the function will trigger =
an undefined behavior and compiler is allowed to perform arbitrary optimiza=
tions (this is a consequence of mixing UB and as-if rules).<br><br>Now an a=
ssert can be defined as:<br><div class=3D"prettyprint" style=3D"background-=
color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: =
solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprin=
t"><div class=3D"subprettyprint"><table><tbody><tr><td class=3D"number"><co=
de></code><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan></td><td class=3D"content"><code class=3D"preprocessor"><span style=3D"=
color: #800;" class=3D"styled-by-prettify">#ifdef</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> NDEBUG<br></span><span style=3D"col=
or: #800;" class=3D"styled-by-prettify"># define ASSERT( PRED ) stati=
c_cast<void>( (PRED) || undefined_behavior() ) #endif</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span></code></td></t=
r></tbody></table></div></code></div><br>This is an information to the comp=
iler: either the condition is true, or you can do whatever you want. I trie=
d to provide a more thorough explanation of the mechanism <a href=3D"http:/=
/akrzemi1.wordpress.com/2011/04/06/assertions/#optimization">here</a>.<br><=
br><br><br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_115_28138020.1354104940049--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 28 Nov 2012 07:15:01 -0800 (PST)
Raw View
------=_Part_139_9856600.1354115701138
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
On Wednesday, November 28, 2012 4:15:39 AM UTC-8, Andrzej Krzemie=F1ski wro=
te:
>
>
>
> W dniu wtorek, 27 listopada 2012 21:26:43 UTC+1 u=BFytkownik Fr=E9d=E9ric=
=20
> TERRAZZONI napisa=B3:
>>
>> The assert() macro is a very useful tool to document invariants that are=
=20
>> supposed to be true at a certain point in the code. Moreover, they also=
=20
>> help the programmer to find bugs since it is expanded to an error-checki=
ng=20
>> code in debug mode. However, in release mode (NDEBUG), this macro is=20
>> expanded to ((void)0). For me, that specific definition of assert leads =
to=20
>> a loss a useful information that could be used by the optimizer.=20
>>
>>
>> For instance, if the optimizer was assert-aware, it would be almost=20
>> possible to emulate the restrict keyword of C99 :
>>
>> void fn_c99(double * restrict a, double * restrict b) { ... } =20
>>
>> void fn_cpp(double * a, double * b) { assert(a!=3Db); ... } // (note: fo=
r=20
>> equivalence, a & b must not be arrays)
>>
>>
>> This is only one example, but we can easily imagine more situations wher=
e=20
>> it could be useful to explicit various constraints (inequalities,=20
>> !=3Dnullptr, ...) that would help the optimizer (to remove useless branc=
hes=20
>> for instance).
>>
>> =20
>>
>> By expliciting all the contraints that we have on the variables:
>>
>> 1- We're giving new hints to the optimizer that it cannot prove itself=
=20
>> (in release mode)
>>
>> 2- We can check the conformance of our code to these assertions (in debu=
g=20
>> mode)
>>
>> =20
>>
>> The current definition of assert() doesn't allow this kind of=20
>> optimization since the compiler doesn't even see the assertions (they ar=
e=20
>> removed by the pre-compiler if NDEBUG is defined). Two little modificati=
ons=20
>> of the standard would be enough to enable it: let the expansion of asser=
t()=20
>> be implementation-defined in release mode + allow assert-based=20
>> optimizations.
>>
>>
>> What do you think about this proposal?
>>
>
> I find such proposal very useful. It would enable some assert-based=20
> optimizations. This suggestion was raised years ago by Niklas Matthies (s=
ee=20
> here<https://groups.google.com/d/msg/comp.std.c++/L95zvmMXN3I/4SlPwAAUV3M=
J>).=20
> It requires that there is some intrinsic function that represents an=20
> undefined behavior that the compiler is aware of:
>
> constexpr bool undefined_behavior() noexcept;
>
> When compiler sees it, it is *guaranteed* that the function will trigger=
=20
> an undefined behavior
>
How exactly do you "guarantee" undefined behavior? It's undefined; by=20
definition, anything can happen.
=20
> and compiler is allowed to perform arbitrary optimizations (this is a=20
> consequence of mixing UB and as-if rules).
>
> Now an assert can be defined as:
>
> #ifdef NDEBUG
> # define ASSERT( PRED ) static_cast<void>( (PRED) || undefined_behavior(=
)=20
> ) #endif
>
> This is an information to the compiler: either the condition is true, or=
=20
> you can do whatever you want. I tried to provide a more thorough=20
> explanation of the mechanism here<http://akrzemi1.wordpress.com/2011/04/0=
6/assertions/#optimization>.=20
>
>
--=20
------=_Part_139_9856600.1354115701138
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>On Wednesday, November 28, 2012 4:15:39 AM UTC-8, Andrzej Krzemie=
=F1ski wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br><br>W dniu wt=
orek, 27 listopada 2012 21:26:43 UTC+1 u=BFytkownik Fr=E9d=E9ric TERRAZZONI=
napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:=
0.8ex;border-left:1px #ccc solid;padding-left:1ex"><p class=3D"MsoNormal">T=
he assert() macro is a very useful tool to document
invariants that are supposed to be true at a certain point in the code.
Moreover, they also help the programmer to find bugs since it is expanded t=
o an
error-checking code in debug mode. However, in release mode (NDEBUG), this
macro is expanded to ((void)0). For me, that specific definition of assert
leads to a loss a useful information that could be used by the optimizer. <=
/p>
<p class=3D"MsoNormal"><br></p>
<p class=3D"MsoNormal">For instance, if the optimizer was assert-aware, it =
would be almost possible to emulate the restrict keyword of C99 :</p>
<p class=3D"MsoNormal">void fn_c99(double * restrict a, double * restrict b=
) { ...
} </p>
<p class=3D"MsoNormal">void fn_cpp(double * a, double * b) { assert(a!=3Db)=
; ...
} // (note: for equivalence, a & b must not be arrays)</p>
<p class=3D"MsoNormal"><br></p>
<p class=3D"MsoNormal">This is only one example, but we can easily imagine =
more
situations where it could be useful to explicit various constraints
(inequalities, !=3Dnullptr, ...) that would help the optimizer (to remove u=
seless branches for instance).</p>
<p class=3D"MsoNormal"> </p>
<p class=3D"MsoNormal">By expliciting all the contraints that we have on th=
e variables:</p>
<p class=3D"MsoNormal">1- We're giving new hints to the optimizer that it c=
annot
prove itself (in release mode)</p>
<p class=3D"MsoNormal">2- We can check the conformance of our code to these=
assertions (in debug mode)</p><p class=3D"MsoNormal"></p>
<p class=3D"MsoNormal"> </p>
<p class=3D"MsoNormal">The current definition of assert() doesn't allow thi=
s kind
of optimization since the compiler doesn't even see the assertions (th=
ey are removed by the pre-compiler if NDEBUG is defined). Two little modifi=
cations of the standard would be enough to enable it:
let the expansion of assert() be implementation-defined in release mode + a=
llow assert-based optimizations.</p><p class=3D"MsoNormal"></p>
<p class=3D"MsoNormal"><br></p>
<p class=3D"MsoNormal">What do you think about this proposal?</p></blockquo=
te><div><br>I find such proposal very useful. It would enable some assert-b=
ased optimizations. This suggestion was raised years ago by Niklas Matthies=
(<a href=3D"https://groups.google.com/d/msg/comp.std.c++/L95zvmMXN3I/4SlPw=
AAUV3MJ" target=3D"_blank">see here</a>). It requires that there is some in=
trinsic function that represents an undefined behavior that the compiler is=
aware of:<br><br><div style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-wo=
rd"><code><div><span style=3D"color:#008">constexpr</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#008">bool</span><span style=3D"colo=
r:#000"> undefined_behavior</span><span style=3D"color:#660">()</span><span=
style=3D"color:#000"> noexcept</span><span style=3D"color:#660">;</span><s=
pan style=3D"color:#000"><br></span></div></code></div><br>When compiler se=
es it, it is <u>guaranteed</u> that the function will trigger an undefined =
behavior</div></blockquote><div><br>How exactly do you "guarantee" undefine=
d behavior? It's undefined; by definition, anything can happen.<br> </=
div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div>and compiler is allow=
ed to perform arbitrary optimizations (this is a consequence of mixing UB a=
nd as-if rules).<br><br>Now an assert can be defined as:<br><div style=3D"b=
ackground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style=
:solid;border-width:1px;word-wrap:break-word"><code><div><table><tbody><tr>=
<td><code></code><span style=3D"color:#000"><br></span></td><td><code><span=
style=3D"color:#800">#ifdef</span><span style=3D"color:#000"> NDEBUG<br></=
span><span style=3D"color:#800"># define ASSERT( PRED ) static_cast&l=
t;void>( (PRED) || undefined_behavior() ) #endif</span><span style=3D"co=
lor:#000"><br></span></code></td></tr></tbody></table></div></code></div><b=
r>This is an information to the compiler: either the condition is true, or =
you can do whatever you want. I tried to provide a more thorough explanatio=
n of the mechanism <a href=3D"http://akrzemi1.wordpress.com/2011/04/06/asse=
rtions/#optimization" target=3D"_blank">here</a>. <br></div></blockquote>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_139_9856600.1354115701138--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Wed, 28 Nov 2012 10:27:23 -0500
Raw View
--20cf306f76b698a9f304cf8fcdb1
Content-Type: text/plain; charset=ISO-8859-1
constexpr bool undefined_behavior() noexcept;
>
>> When compiler sees it, it is *guaranteed* that the function will trigger
>> an undefined behavior
>>
>
> How exactly do you "guarantee" undefined behavior? It's undefined; by
> definition, anything can happen.
>
>
Exactly - how can you _not_ guarantee it? Whatever happens next,
satisfies "undefined". :-)
Basically, in the standard say something like "the behaviour of
std::undefined_behaviour() is undefined".
And thus after that function is called, the compiler is free to do whatever
it likes with the code.
The real question is whether we want _that_ much leeway. It really
probably doesn't change anything - most asserts() are checking against
conditions that would lead to undefined behaviour anyhow.
Tony
--
--20cf306f76b698a9f304cf8fcdb1
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<code><div><span style=3D"color:#008">constexpr</span><span style> </span><=
span style=3D"color:#008">bool</span><span style> undefined_behavior</span>=
<span style=3D"color:#660">()</span><span style> noexcept</span><span style=
=3D"color:#660">;</span><span style><br>
</span></div></code><div class=3D"gmail_quote"><blockquote class=3D"gmail_q=
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div class=3D"im"><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><br>When compiler sees it, it is <u>guaranteed</u> that the function w=
ill trigger an undefined behavior</div></blockquote></div><div><br>How exac=
tly do you "guarantee" undefined behavior? It's undefined; by=
definition, anything can happen.<br>
<br></div></blockquote><div><br>Exactly - how can you _not_ guarantee it? =
=A0 Whatever happens next, satisfies "undefined".=A0 :-)<br>Basic=
ally, in the standard say something like=A0 "the behaviour of std::und=
efined_behaviour() is undefined".<br>
And thus after that function is called, the compiler is free to do whatever=
it likes with the code.<br><br>The real question is whether we want _that_=
much leeway.=A0 It really probably doesn't change anything - most asse=
rts() are checking against conditions that would lead to undefined behaviou=
r anyhow.<br>
</div></div><br>Tony<br>
<p></p>
-- <br />
<br />
<br />
<br />
--20cf306f76b698a9f304cf8fcdb1--
.
Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Wed, 28 Nov 2012 16:31:04 +0100
Raw View
--047d7b33d1a60576f704cf8fdc5a
Content-Type: text/plain; charset=ISO-8859-1
On Wed, Nov 28, 2012 at 4:27 PM, Tony V E <tvaneerd@gmail.com> wrote:
> constexpr bool undefined_behavior() noexcept;
>
>>
>>> When compiler sees it, it is *guaranteed* that the function will
>>> trigger an undefined behavior
>>>
>>
>> How exactly do you "guarantee" undefined behavior? It's undefined; by
>> definition, anything can happen.
>>
>>
> Exactly - how can you _not_ guarantee it? Whatever happens next,
> satisfies "undefined". :-)
> Basically, in the standard say something like "the behaviour of
> std::undefined_behaviour() is undefined".
> And thus after that function is called, the compiler is free to do
> whatever it likes with the code.
>
>
What do we need the function for then? Just do like we have been doing all
this time: say that if the condition does not hold, the behaviour is
undefined.
Martinho
--
--047d7b33d1a60576f704cf8fdc5a
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<br><div class=3D"gmail_quote">On Wed, Nov 28, 2012 at 4:27 PM, Tony V E <s=
pan dir=3D"ltr"><<a href=3D"mailto:tvaneerd@gmail.com" target=3D"_blank"=
>tvaneerd@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quo=
te" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"=
>
<code><div><span style=3D"color:#008">constexpr</span><span> </span><span s=
tyle=3D"color:#008">bool</span><span> undefined_behavior</span><span style=
=3D"color:#660">()</span><span> noexcept</span><span style=3D"color:#660">;=
</span><span><br>
</span></div></code><div class=3D"gmail_quote"><div class=3D"im"><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex"><div><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><br>When compiler sees it, it is <u>guaranteed</u> that the function w=
ill trigger an undefined behavior</div></blockquote></div><div><br>How exac=
tly do you "guarantee" undefined behavior? It's undefined; by=
definition, anything can happen.<br>
<br></div></blockquote></div><div><br>Exactly - how can you _not_ guarantee=
it? =A0 Whatever happens next, satisfies "undefined".=A0 :-)<br>=
Basically, in the standard say something like=A0 "the behaviour of std=
::undefined_behaviour() is undefined".<br>
And thus after that function is called, the compiler is free to do whatever=
it likes with the code.<br><br></div></div></blockquote><div><br>What do w=
e need the function for then? Just do like we have been doing all this time=
: say that if the condition does not hold, the behaviour is undefined.<br>
<br clear=3D"all">Martinho<br>
<br>=A0</div></div><br>
<p></p>
-- <br />
<br />
<br />
<br />
--047d7b33d1a60576f704cf8fdc5a--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 28 Nov 2012 07:58:21 -0800 (PST)
Raw View
------=_Part_424_9511776.1354118301046
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu =B6roda, 28 listopada 2012 16:31:04 UTC+1 u=BFytkownik R. Martinho=
=20
Fernandes napisa=B3:
>
>
> On Wed, Nov 28, 2012 at 4:27 PM, Tony V E <tvan...@gmail.com <javascript:=
>
> > wrote:
>
>> constexpr bool undefined_behavior() noexcept;
>>
>>>
>>>> When compiler sees it, it is *guaranteed* that the function will=20
>>>> trigger an undefined behavior
>>>>
>>>
>>> How exactly do you "guarantee" undefined behavior? It's undefined; by=
=20
>>> definition, anything can happen.
>>>
>>>
>> Exactly - how can you _not_ guarantee it? Whatever happens next,=20
>> satisfies "undefined". :-)
>> Basically, in the standard say something like "the behaviour of=20
>> std::undefined_behaviour() is undefined".
>> And thus after that function is called, the compiler is free to do=20
>> whatever it likes with the code.
>>
>>
> What do we need the function for then? Just do like we have been doing al=
l=20
> this time: say that if the condition does not hold, the behaviour is=20
> undefined.
>
> Martinho
>
Perhaps I used wrong words. I will rename the function from=20
undefined_behavior to impossible_to_get_here. This function is not a normal=
=20
function it is a compiler "intrinsic", recognized by the compiler. The=20
provision that the compiler obtains when compiling the execution of this=20
function is that if this function is (or would be) executed, the compiler=
=20
can depart from the constraint that it normally works under: guaranteeing=
=20
certain observable behavior of the program.
This is the value that this special function offers: it allows the compiler=
=20
to do something that it typically is not allowed to do: arbitrarily change=
=20
the observable behavior of the program. But it is not allowing mess though,=
=20
because we are only allowing this provision if assertion would fail.=20
Normal UB is not controlled by the compiler. You (the programmer) tell the=
=20
program to do something wrong, and the compiler just correctly transforms=
=20
that to a binary code. In this proposal the "pseudo UB" would work=20
differently. The compiler (only when you allow it to) can modify the=20
program behavior in a way that you cannot control, but to the benefit of=20
your program. For instance, the following code:
int passengers =3D getPassengers();=20
switch( passengers % 2 ) {=20
case 1:=20
return handleOdd( passengers );=20
case 2:=20
return handleEven( passengers );=20
default:=20
impossible_to_get_here();
// equivalent to assert(false);
}
Would allow the compiler to rearrange the code to:
switch( passengers % 2 ) {=20
case 1:=20
return handleOdd( passengers );=20
default:=20
return handleEven( passengers ); }=20
Even though as-if rule would not allow that.
=20
--=20
------=_Part_424_9511776.1354118301046
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu =B6roda, 28 listopada 2012 16:31:04 UTC+1 u=BFytkownik R. Ma=
rtinho Fernandes napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br=
><div class=3D"gmail_quote">On Wed, Nov 28, 2012 at 4:27 PM, Tony V E <span=
dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-m=
ailto=3D"gKU7gUlTt5gJ">tvan...@gmail.com</a>></span> wrote:<br><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex">
<code><div><span style=3D"color:#008">constexpr</span><span> </span><span s=
tyle=3D"color:#008">bool</span><span> undefined_behavior</span><span style=
=3D"color:#660">()</span><span> noexcept</span><span style=3D"color:#660">;=
</span><span><br>
</span></div></code><div class=3D"gmail_quote"><div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><br>When compiler sees it, it is <u>guaranteed</u> that the function w=
ill trigger an undefined behavior</div></blockquote></div><div><br>How exac=
tly do you "guarantee" undefined behavior? It's undefined; by definition, a=
nything can happen.<br>
<br></div></blockquote></div><div><br>Exactly - how can you _not_ guarantee=
it? Whatever happens next, satisfies "undefined". :-)<br>Basi=
cally, in the standard say something like "the behaviour of std::unde=
fined_behaviour() is undefined".<br>
And thus after that function is called, the compiler is free to do whatever=
it likes with the code.<br><br></div></div></blockquote><div><br>What do w=
e need the function for then? Just do like we have been doing all this time=
: say that if the condition does not hold, the behaviour is undefined.<br>
<br clear=3D"all">Martinho<br></div></div></blockquote><div><br>Perhaps I u=
sed wrong words. I will rename the function from <span style=3D"font-family=
: courier new,monospace;">undefined_behavior</span> to <span style=3D"font-=
family: courier new,monospace;">impossible_to_get_here</span>. This functio=
n is not a normal function it is a compiler "intrinsic", recognized by the =
compiler. The provision that the compiler obtains when compiling the execut=
ion of this function is that if this function is (or would be) executed, th=
e compiler can depart from the constraint that it normally works under: gua=
ranteeing certain observable behavior of the program.<br><br>This is the va=
lue that this special function offers: it allows the compiler to do somethi=
ng that it typically is not allowed to do: arbitrarily change the observabl=
e behavior of the program. But it is not allowing mess though, because we a=
re only allowing this provision if assertion would fail. <br><br>Normal UB =
is not controlled by the compiler. You (the programmer) tell the program to=
do something wrong, and the compiler just correctly transforms that to a b=
inary code. In this proposal the "pseudo UB" would work differently. The co=
mpiler (only when you allow it to) can modify the program behavior in a way=
that you cannot control, but to the benefit of your program. For instance,=
the following code:<br><br><pre><div class=3D"prettyprint" style=3D"backgr=
ound-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-st=
yle: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D=
"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> passengers </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> getPassengers</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> <br></span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>switch</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> passengers =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">%</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">2</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> <br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">cas=
e</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> <br> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> handleOdd</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> passengers </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> <br></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">case</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> handleEven</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> passengers </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> <br></span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">default</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> <br> </span><span style=3D"font-family=
: courier new,monospace;"><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">impossible_to_get_here</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br> </span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">// equivalent to assert(false);</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br></span></span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">}</span></div></code></div><br><span s=
tyle=3D"font-family: arial,sans-serif;">Would allow the compiler to rearran=
ge the code to:<br><br></span><span style=3D"font-family: arial,sans-serif;=
"><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250);=
border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; =
word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpretty=
print"><span style=3D"color: #008;" class=3D"styled-by-prettify">switch</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> passengers </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">%</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">2</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br></=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">case</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> <br> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> handleOdd</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> passengers </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> <br></span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">default</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">re=
turn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> handl=
eEven</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> passengers </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> <br></span></div></code></div><br>Ev=
en though as-if rule would not allow that.<br></span></pre> </div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_424_9511776.1354118301046--
.
Author: Lawrence Crowl <crowl@googlers.com>
Date: Wed, 28 Nov 2012 14:49:42 -0800
Raw View
On 11/27/12, Fr=E9d=E9ric TERRAZZONI <akryus@gmail.com> wrote:
> The assert() macro is a very useful tool to document invariants
> that are supposed to be true at a certain point in the
> code. Moreover, they also help the programmer to find bugs since
> it is expanded to an error-checking code in debug mode. However,
> in release mode (NDEBUG), this macro is expanded to ((void)0). For
> me, that specific definition of assert leads to a loss a useful
> information that could be used by the optimizer.
>
> For instance, if the optimizer was assert-aware, it would be
> almost possible to emulate the restrict keyword of C99 :
>
> void fn_c99(double * restrict a, double * restrict b) { ... }
>
> void fn_cpp(double * a, double * b) { assert(a!=3Db); ... }
> // (note: for equivalence, a & b must not be arrays)
>
> This is only one example, but we can easily imagine more situations
> where it could be useful to explicit various constraints
> (inequalities, !=3Dnullptr, ...) that would help the optimizer
> (to remove useless branches for instance).
>
> By expliciting all the contraints that we have on the variables:
>
> 1- We're giving new hints to the optimizer that it cannot prove
> itself (in release mode)
>
> 2- We can check the conformance of our code to these assertions
> (in debug mode)
>
> The current definition of assert() doesn't allow this kind of
> optimization since the compiler doesn't even see the assertions
> (they are removed by the pre-compiler if NDEBUG is defined). Two
> little modifications of the standard would be enough to enable
> it: let the expansion of assert() be implementation-defined in
> release mode + allow assert-based optimizations.
>
> What do you think about this proposal?
I think rather than tinker with a macro with problematic
characteristics, we should have targeted language features.
See N1962 Proposal to add Contract Programming to C++ (revision 4)
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2006/n1962.html
and N1867 Synergies between Contract Programming, Concepts and
Static Assertions
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1867.html
--=20
Lawrence Crowl
--=20
.
Author: =?UTF-8?Q?Fr=C3=A9d=C3=A9ric_TERRAZZONI?= <akryus@gmail.com>
Date: Thu, 29 Nov 2012 07:40:54 -0800 (PST)
Raw View
------=_Part_52_23754399.1354203654321
Content-Type: text/plain; charset=ISO-8859-1
@Andrzej Krzemienski:
Like Martinho, I don't understand why such a primitive should be exposed
(undefined_behavior() or impossible_to_get_here()).
It is much more simple to say right in the standard :
- If NDEBUG is undefined, then assert(false) abort the program.
- If NDEBUG is defined, then assert(false) is UB (instead of doing nothing,
in the current version)
The actual definition of the assert() macro should be left as an
implementation detail. Compared to the current version of assert(), I do
not see any drawback : it won't break code that is not already-broken, and
it gives an easy way to help the compiler producing better output.
@Lawrence Crowl:
The contract programming proposal is indeed better to deal with class
invariants & pre/post-conditions. But it may not be always the best
solution, especially if we are inside a function/method and we're asserting
things about intermediary results.
For instance, if at some point we want to benefit from automatic
vectorization then we would be able to write :
float *a,*b,*c;
size_t n;
// a,b,c are arrays of size n
assert(c + n <= a || a + n <= c); //a doesn't alias c
assert(c + n <= b || b + n <= c); //b doesn't alias c
// vectorizable loop
for(size_t i = 0 ; i < n ; i++)
c[i] = a[i]*b[i];
Notice that these two assertions doesn't prevent a and b to overlap (it is
not possible to emulate this with the "restrict" keyword, because it's not
expressive enough)
--
------=_Part_52_23754399.1354203654321
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div>@Andrzej Krzemienski:</div><div><br></div><div>Like Martinho, I don't =
understand why such a primitive should be exposed (undefined_behavior() or =
impossible_to_get_here()).</div><div><br></div><div>It is much more simple =
to say right in the standard :</div><div>- If NDEBUG is undefined, then ass=
ert(false) abort the program.</div><div>- If NDEBUG is defined, then assert=
(false) is UB (instead of doing nothing, in the current version)</div><div>=
<br></div><div>The actual definition of the assert() macro should be left a=
s an implementation detail. Compared to the current version of assert(), I =
do not see any drawback : it won't break code that is not already-broken, a=
nd it gives an easy way to help the compiler producing better output.</div>=
<div><br></div><div>@Lawrence Crowl:</div><div><br></div><div>The contract =
programming proposal is indeed better to deal with class invariants & p=
re/post-conditions. But it may not be always the best solution, especially =
if we are inside a function/method and we're asserting things about interme=
diary results.</div><div><br></div><div>For instance, if at some point we w=
ant to benefit from automatic vectorization then we would be able to write =
:</div><div><br></div><div>float *a,*b,*c;</div><div>size_t n;</div><div><b=
r></div><div>// a,b,c are arrays of size n</div><div><br></div><div>assert(=
c + n <=3D a || a + n <=3D c); //a doesn't alias c</div><div>assert(c=
+ n <=3D b || b + n <=3D c); //b doesn't alias c</div><div><br></div=
><div>// vectorizable loop</div><div>for(size_t i =3D 0 ; i < n ; i++)</=
div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>c=
[i] =3D a[i]*b[i];</div><div><span class=3D"Apple-tab-span" style=3D"white-=
space:pre"> </span></div><div>Notice that these two assertions doesn't prev=
ent a and b to overlap (it is not possible to emulate this with the "restri=
ct" keyword, because it's not expressive enough)</div><div><br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_52_23754399.1354203654321--
.
Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Thu, 29 Nov 2012 07:59:04 -0800 (PST)
Raw View
------=_Part_98_28077743.1354204744172
Content-Type: text/plain; charset=ISO-8859-1
1/ Is this a standardization of a feature already provided by compilers?
Until more indication that it would really be useful, I tend to think that
if it was really useful for performance, compilers would have provided the
feature in an implementation specific way and I don't remember having seen
any. Well, gcc has __builtin_unreachable() but it seems designed for
something else. I'd have expected a __builtin_assume if the feature was
available.
2/ I'd provide this in a way not tied to an existing feature. It may be
tempting, but I know projects which are using assert so that it fails when
compiled without NDEBUG and providing an alternate execution path when
compiled with NDEBUG.
Yours,
--
Jean-Marc
--
------=_Part_98_28077743.1354204744172
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
1/ Is this a standardization of a feature already provided by compilers?<br=
><br>Until more indication that it would really be useful, I tend to think =
that if it was really useful for performance, compilers would have provided=
the feature in an implementation specific way and I don't remember having =
seen any. Well, gcc has __builtin_unreachable() but it seems designed for s=
omething else. I'd have expected a __builtin_assume if the feature was avai=
lable.<br><br>2/ I'd provide this in a way not tied to an existing feature.=
It may be tempting, but I know projects which are using assert so that it =
fails when compiled without NDEBUG and providing an alternate execution pat=
h when compiled with NDEBUG.<br><br>Yours,<br><br>-- <br>Jean-Marc<br>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_98_28077743.1354204744172--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Thu, 29 Nov 2012 08:02:31 -0800 (PST)
Raw View
------=_Part_102_21940591.1354204951801
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu czwartek, 29 listopada 2012 16:40:54 UTC+1 u=BFytkownik Fr=E9d=E9ric=
=20
TERRAZZONI napisa=B3:
>
> @Andrzej Krzemienski:
>
> Like Martinho, I don't understand why such a primitive should be exposed=
=20
> (undefined_behavior() or impossible_to_get_here()).
>
> It is much more simple to say right in the standard :
> - If NDEBUG is undefined, then assert(false) abort the program.
> - If NDEBUG is defined, then assert(false) is UB (instead of doing=20
> nothing, in the current version)
>
> The actual definition of the assert() macro should be left as an=20
> implementation detail. Compared to the current version of assert(), I do=
=20
> not see any drawback : it won't break code that is not already-broken, an=
d=20
> it gives an easy way to help the compiler producing better output.
>
Indeed, the way you present it above, it is much simpler and gives the same=
=20
power to the compiler.=20
=20
> @Lawrence Crowl:
>
> The contract programming proposal is indeed better to deal with class=20
> invariants & pre/post-conditions. But it may not be always the best=20
> solution, especially if we are inside a function/method and we're asserti=
ng=20
> things about intermediary results.
>
One other argument for "enhancing" an assert as you propose is that it=20
requires very small change to the standard; counter to contract-programming=
=20
proposal (which is good otherwise).
--=20
------=_Part_102_21940591.1354204951801
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu czwartek, 29 listopada 2012 16:40:54 UTC+1 u=BFytkownik Fr=
=E9d=E9ric TERRAZZONI napisa=B3:<blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
"><div>@Andrzej Krzemienski:</div><div><br></div><div>Like Martinho, I don'=
t understand why such a primitive should be exposed (undefined_behavior() o=
r impossible_to_get_here()).</div><div><br></div><div>It is much more simpl=
e to say right in the standard :</div><div>- If NDEBUG is undefined, then a=
ssert(false) abort the program.</div><div>- If NDEBUG is defined, then asse=
rt(false) is UB (instead of doing nothing, in the current version)</div><di=
v><br></div><div>The actual definition of the assert() macro should be left=
as an implementation detail. Compared to the current version of assert(), =
I do not see any drawback : it won't break code that is not already-broken,=
and it gives an easy way to help the compiler producing better output.</di=
v></blockquote><div><br>Indeed, the way you present it above, it is much si=
mpler and gives the same power to the compiler. <br> <br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div>@Lawrence Crowl:</div><div><br><=
/div><div>The contract programming proposal is indeed better to deal with c=
lass invariants & pre/post-conditions. But it may not be always the bes=
t solution, especially if we are inside a function/method and we're asserti=
ng things about intermediary results.</div></blockquote><div><br>One other =
argument for "enhancing" an assert as you propose is that it requires very =
small change to the standard; counter to contract-programming proposal (whi=
ch is good otherwise).</div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_102_21940591.1354204951801--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 29 Nov 2012 11:49:35 -0500
Raw View
On Thu, Nov 29, 2012 at 10:59 AM, Jean-Marc Bourguet
<jm.bourguet@gmail.com> wrote:
>
> 2/ I'd provide this in a way not tied to an existing feature. It may be
> tempting, but I know projects which are using assert so that it fails when
> compiled without NDEBUG and providing an alternate execution path when
> compiled with NDEBUG.
>
Yes, I've seen plenty of code that looks like:
assert(p != NULL);
if (p == NULL)
return false; // or etc
You can argue whether that makes sense or not (I think there are valid
arguments on both sides), but either way, it is common enough that we
can't change assert's NDEBUG behaviour.
So a std::assume(expr) might be nicer.
Tony
--
.
Author: =?UTF-8?Q?Fr=C3=A9d=C3=A9ric_TERRAZZONI?= <akryus@gmail.com>
Date: Thu, 29 Nov 2012 09:35:03 -0800 (PST)
Raw View
------=_Part_256_30070768.1354210503381
Content-Type: text/plain; charset=ISO-8859-1
I dislike this code, and I've (hopefully) never seen this. It looks like a
quick "bugfix". If I write a function taking a pointer argument, I want its
"contract" to be the same no matter I've defined NDEBUG or not:
- If it doesn't accept a nullptr, then I assert(p!=nullptr); and I document
it
- If it can handle nullptr, then I use a conditionnal statement and I
document it
Consequently, when this software is running in real word (with NDEBUG
naturally), some new vicious code paths are made available. Certainly, some
of them have not been properly tested since they're only reachable with
NDEBUG. Good luck to debug them afterwards (and no, you cannot disable
NDEBUG because the program is likely to abort before the actual bug).
It's worth noting that this kind of code could be warned as "potentially
dangerous" by the compilers if the assert was improved :
assert(condition);
if(!condition) { ... } // warning
Anyway, I can understand your opinion, and I also understand that some
people may want to use it (it is valid C++ code according to the standard
after all).
However, I still see some problems with "std::assume": (expr) is not
supposed to be evaluated if NDEBUG is defined, so it cannot be a
function/class. If it is a keyword, it's likely to break existing code. The
only possibility is to implement it as a macro (in a separate header).
Since, you cannot put a macro in a namespace, your "std::assume" becomes
"assume".
--
------=_Part_256_30070768.1354210503381
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div>I dislike this code, and I've (hopefully) never seen this. It looks li=
ke a quick "bugfix". If I write a function taking a pointer argument, I wan=
t its "contract" to be the same no matter I've defined NDEBUG or not: =
</div><div><br></div><div>- If it doesn't accept a nullptr, then I assert(p=
!=3Dnullptr); and I document it</div><div>- If it can handle nullptr, then =
I use a conditionnal statement and I document it</div><div><br></div><div>C=
onsequently, when this software is running in real word (with NDEBUG natura=
lly), some new vicious code paths are made available. Certainly, some of th=
em have not been properly tested since they're only reachable with NDEBUG. =
Good luck to debug them afterwards (and no, you cannot disable NDEBUG becau=
se the program is likely to abort before the actual bug).</div><div><br></d=
iv><div>It's worth noting that this kind of code could be warned as "potent=
ially dangerous" by the compilers if the assert was improved :</div><div>as=
sert(condition);</div><div>if(!condition) { ... } // warning&n=
bsp;</div><div><br></div><div>Anyway, I can understand your opinion, and I =
also understand that some people may want to use it (it is valid C++ code a=
ccording to the standard after all).</div><div><br></div><div>However, I st=
ill see some problems with "std::assume": (expr) is not supposed to be eval=
uated if NDEBUG is defined, so it cannot be a function/class. If it is a ke=
yword, it's likely to break existing code. The only possibility is to imple=
ment it as a macro (in a separate header). Since, you cannot put a macro in=
a namespace, your "std::assume" becomes "assume".</div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_256_30070768.1354210503381--
.
Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Thu, 29 Nov 2012 18:47:55 +0100
Raw View
--047d7b3390253b207004cfa5e3ed
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On Thu, Nov 29, 2012 at 6:35 PM, Fr=E9d=E9ric TERRAZZONI <akryus@gmail.com>=
wrote:
>
>
> It's worth noting that this kind of code could be warned as "potentially
> dangerous" by the compilers if the assert was improved :
> assert(condition);
> if(!condition) { ... } // warning
>
>
As most warnings, this code can still be warning by compilers and static
analysers, regardless of what the standard says about assert being
"improved" or not. The standard has no say in what warnings can be emitted.
If you want this kind of warning, request them of the compiler writers, not
of the SC.
Martinho
--=20
--047d7b3390253b207004cfa5e3ed
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<br><div class=3D"gmail_quote">On Thu, Nov 29, 2012 at 6:35 PM, Fr=E9d=E9ri=
c TERRAZZONI <span dir=3D"ltr"><<a href=3D"mailto:akryus@gmail.com" targ=
et=3D"_blank">akryus@gmail.com</a>></span> wrote:<blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex">
<div><br></div><div>It's worth noting that this kind of code could be w=
arned as "potentially dangerous" by the compilers if the assert w=
as improved :</div><div>assert(condition);</div><div>if(!condition) { ... }=
=A0 =A0// warning=A0</div>
<div><br></div></blockquote><div><br>As most warnings, this code can still =
be warning by compilers and static analysers, regardless of what the standa=
rd says about assert being "improved" or not. The standard has no=
say in what warnings can be emitted. If you want this kind of warning, req=
uest them of the compiler writers, not of the SC.<br>
<br>Martinho<br></div></div>
<p></p>
-- <br />
<br />
<br />
<br />
--047d7b3390253b207004cfa5e3ed--
.
Author: =?UTF-8?Q?Fr=C3=A9d=C3=A9ric_TERRAZZONI?= <akryus@gmail.com>
Date: Thu, 29 Nov 2012 09:56:33 -0800 (PST)
Raw View
------=_Part_230_16944.1354211793466
Content-Type: text/plain; charset=ISO-8859-1
Yes of course, I was not asking for specific warnings to be standardized. I
was trying to say that if assert() was improved, then it would be easy to
fix all these incompatible programs if the compilers were able to generate
good warnings.
--
------=_Part_230_16944.1354211793466
Content-Type: text/html; charset=ISO-8859-1
Yes of course, I was not asking for specific warnings to be standardized. I was trying to say that if assert() was improved, then it would be easy to fix all these incompatible programs if the compilers were able to generate good warnings. <br>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_230_16944.1354211793466--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 29 Nov 2012 13:15:23 -0500
Raw View
On Thu, Nov 29, 2012 at 12:35 PM, Fr=E9d=E9ric TERRAZZONI <akryus@gmail.com=
> wrote:
>
> However, I still see some problems with "std::assume": (expr) is not
> supposed to be evaluated if NDEBUG is defined, so it cannot be a
> function/class. If it is a keyword, it's likely to break existing code. T=
he
> only possibility is to implement it as a macro (in a separate header).
> Since, you cannot put a macro in a namespace, your "std::assume" becomes
> "assume".
>
Well, unless we start allowing namespaced keywords. :-)
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Thu, 29 Nov 2012 11:18:26 -0800 (PST)
Raw View
------=_Part_91_29240959.1354216706482
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu czwartek, 29 listopada 2012 18:35:03 UTC+1 u=BFytkownik Fr=E9d=E9ric=
=20
TERRAZZONI napisa=B3:
>
> I dislike this code, and I've (hopefully) never seen this. It looks like =
a=20
> quick "bugfix". If I write a function taking a pointer argument, I want i=
ts=20
> "contract" to be the same no matter I've defined NDEBUG or not:=20
>
> - If it doesn't accept a nullptr, then I assert(p!=3Dnullptr); and I=20
> document it
> - If it can handle nullptr, then I use a conditionnal statement and I=20
> document it
>
> Consequently, when this software is running in real word (with NDEBUG=20
> naturally), some new vicious code paths are made available. Certainly, so=
me=20
> of them have not been properly tested since they're only reachable with=
=20
> NDEBUG. Good luck to debug them afterwards (and no, you cannot disable=20
> NDEBUG because the program is likely to abort before the actual bug).
>
> It's worth noting that this kind of code could be warned as "potentially=
=20
> dangerous" by the compilers if the assert was improved :
> assert(condition);
> if(!condition) { ... } // warning=20
>
> Anyway, I can understand your opinion, and I also understand that some=20
> people may want to use it (it is valid C++ code according to the standard=
=20
> after all).
>
How about introducing a third "mode" of macro assert()? E.g., If NDEBUG is=
=20
defined (to nearly any value) leave the behavior as it is today, but if it=
=20
is defined to some special value, say 10, then apply the "UB" behavior. Or,=
=20
Introduce another macro similar to NDEBUG, say XNDEBUG: if defined=20
assertion failure is an UB?
Regards,
&rzej
--=20
------=_Part_91_29240959.1354216706482
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu czwartek, 29 listopada 2012 18:35:03 UTC+1 u=BFytkownik Fr=
=E9d=E9ric TERRAZZONI napisa=B3:<blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
"><div>I dislike this code, and I've (hopefully) never seen this. It looks =
like a quick "bugfix". If I write a function taking a pointer argument, I w=
ant its "contract" to be the same no matter I've defined NDEBUG or not:&nbs=
p;</div><div><br></div><div>- If it doesn't accept a nullptr, then I assert=
(p!=3Dnullptr); and I document it</div><div>- If it can handle nullptr, the=
n I use a conditionnal statement and I document it</div><div><br></div><div=
>Consequently, when this software is running in real word (with NDEBUG natu=
rally), some new vicious code paths are made available. Certainly, some of =
them have not been properly tested since they're only reachable with NDEBUG=
.. Good luck to debug them afterwards (and no, you cannot disable NDEBUG bec=
ause the program is likely to abort before the actual bug).</div><div><br><=
/div><div>It's worth noting that this kind of code could be warned as "pote=
ntially dangerous" by the compilers if the assert was improved :</div><div>=
assert(condition);</div><div>if(!condition) { ... } // warning=
</div><div><br></div><div>Anyway, I can understand your opinion, and =
I also understand that some people may want to use it (it is valid C++ code=
according to the standard after all).</div></blockquote><div><br>How about=
introducing a third "mode" of macro assert()? E.g., If NDEBUG is defined (=
to nearly any value) leave the behavior as it is today, but if it is define=
d to some special value, say 10, then apply the "UB" behavior. Or, Introduc=
e another macro similar to NDEBUG, say XNDEBUG: if defined assertion failur=
e is an UB?<br><br>Regards,<br>&rzej<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_91_29240959.1354216706482--
.
Author: =?UTF-8?Q?Fr=C3=A9d=C3=A9ric_TERRAZZONI?= <akryus@gmail.com>
Date: Thu, 29 Nov 2012 11:36:01 -0800 (PST)
Raw View
------=_Part_452_8439049.1354217761993
Content-Type: text/plain; charset=ISO-8859-1
I like the idea of having a 3-modes assert (more than the introduction of
another "word" having a similar semantic which could lead to
confusion). However some problems need to be addressed :
1- Using a special value of NDEBUG is not very elegant :
* NDEBUG undefined : check the assertion at runtime
* NDEBUG defined (any value) : do nothing
* NDEBUG defined (one particular value) : UB if condition is false
The 3 possibles value are not "symmetric". Moreover, which the particular
value could we use ? If we choose a simple one (1,0,-1...), it's likely to
be already used by some people and it could break their codes.
2- Using a new macro (XNDEBUG) is also problematic because we would have 4
states :
* NDEBUG undefined + XNDEBUG undefined : check assertion at runtime
* NDEBUG undefined + XNDEBUG defined : UB if condition is false ?
* NDEBUG defined+ XNDEBUG undefined : do nothing
* NDEBUG defined+ XNDEBUG defined : UB if condition is false ?
--
------=_Part_452_8439049.1354217761993
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
I like the idea of having a 3-modes assert (more than the introduction of a=
nother "word" having a similar semantic which could lead to confusion).&nbs=
p;However some problems need to be addressed :<div><div><br><div>1- Using a=
special value of NDEBUG is not very elegant :</div><div><br></div><div>&nb=
sp; * NDEBUG undefined : check the assertion at runtime</div><div>&n=
bsp; * NDEBUG defined (any value) : do nothing<br><div> =
* NDEBUG defined (one particular value) : UB if condition is false</div></=
div><div><br></div><div>The 3 possibles value are not "symmetric". Moreover=
, which the particular value could we use ? If we choose a simple one (1,0,=
-1...), it's likely to be already used by some people and it could break th=
eir codes.</div><div><br></div><div>2- Using a new macro (XNDEBUG) is also =
problematic because we would have 4 states :</div><div><br></div><div><div>=
* NDEBUG undefined + XNDEBUG undefined : check assertion at r=
untime</div></div><div><div> * NDEBUG undefined + XNDEBUG defi=
ned : UB if condition is false ?</div></div><div><div> =
* NDEBUG defined+ XNDEBUG undefined : do nothing</div></div><d=
iv><div> * NDEBUG defined+ XNDEBUG defined : UB=
if condition is false ?</div></div><div><br></div><div><br></div=
><div><br></div><div><br></div><div><br></div><div><br></div></div></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_452_8439049.1354217761993--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Thu, 29 Nov 2012 11:43:54 -0800 (PST)
Raw View
------=_Part_242_30494325.1354218234456
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu czwartek, 29 listopada 2012 20:36:01 UTC+1 u=BFytkownik Fr=E9d=E9ric=
=20
TERRAZZONI napisa=B3:
>
> I like the idea of having a 3-modes assert (more than the introduction of=
=20
> another "word" having a similar semantic which could lead to=20
> confusion). However some problems need to be addressed :
>
> 1- Using a special value of NDEBUG is not very elegant :
>
> * NDEBUG undefined : check the assertion at runtime
> * NDEBUG defined (any value) : do nothing
> * NDEBUG defined (one particular value) : UB if condition is false
>
> The 3 possibles value are not "symmetric". Moreover, which the particular=
=20
> value could we use ? If we choose a simple one (1,0,-1...), it's likely t=
o=20
> be already used by some people and it could break their codes.
>
> 2- Using a new macro (XNDEBUG) is also problematic because we would have =
4=20
> states :
>
> * NDEBUG undefined + XNDEBUG undefined : check assertion at runtime
> * NDEBUG undefined + XNDEBUG defined : UB if condition is false ?
> * NDEBUG defined+ XNDEBUG undefined : do nothing
> * NDEBUG defined+ XNDEBUG defined : UB if condition is false ?
>
One possible answer to question 2:
=20
- NDEBUG undefined + XNDEBUG undefined : check assertion at runtime
- NDEBUG undefined + XNDEBUG defined : UB if condition is false
- NDEBUG defined+ XNDEBUG undefined : do nothing
- NDEBUG defined+ XNDEBUG defined -- this is a compile-time error
This would avoid the situation where two people inadvertently define either=
=20
macro with different intentions in mind.
--=20
------=_Part_242_30494325.1354218234456
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu czwartek, 29 listopada 2012 20:36:01 UTC+1 u=BFytkownik Fr=
=E9d=E9ric TERRAZZONI napisa=B3:<blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
">I like the idea of having a 3-modes assert (more than the introduction of=
another "word" having a similar semantic which could lead to confusion).&n=
bsp;However some problems need to be addressed :<div><div><br><div>1- Using=
a special value of NDEBUG is not very elegant :</div><div><br></div><div>&=
nbsp; * NDEBUG undefined : check the assertion at runtime</div><div>=
* NDEBUG defined (any value) : do nothing<br><div> &nbs=
p; * NDEBUG defined (one particular value) : UB if condition is false</div>=
</div><div><br></div><div>The 3 possibles value are not "symmetric". Moreov=
er, which the particular value could we use ? If we choose a simple one (1,=
0,-1...), it's likely to be already used by some people and it could break =
their codes.</div><div><br></div><div>2- Using a new macro (XNDEBUG) is als=
o problematic because we would have 4 states :</div><div><br></div><div><di=
v> * NDEBUG undefined + XNDEBUG undefined : check assertion at=
runtime</div></div><div><div> * NDEBUG undefined + XNDEBUG de=
fined : UB if condition is false ?</div></div><div><div>&nbs=
p; * NDEBUG defined+ XNDEBUG undefined : do nothing</div></div>=
<div><div> * NDEBUG defined+ XNDEBUG defined : =
UB if condition is false ?</div></div></div></div></blockquote><d=
iv><br>One possible answer to question 2:<br> <br><ul><li>NDEBUG undef=
ined + XNDEBUG undefined : check assertion at runtime</li><li>NDEBUG undefi=
ned + XNDEBUG defined : UB if condition is false<br></li><li=
>NDEBUG defined+ XNDEBUG undefined : do nothing</li><li>NDEBUG de=
fined+ XNDEBUG defined -- this is a compile-time error</li></ul><p>Thi=
s would avoid the situation where two people inadvertently define either ma=
cro with different intentions in mind.<br></p><br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_242_30494325.1354218234456--
.
Author: =?UTF-8?Q?Fr=C3=A9d=C3=A9ric_TERRAZZONI?= <akryus@gmail.com>
Date: Thu, 29 Nov 2012 12:06:12 -0800 (PST)
Raw View
------=_Part_411_25899392.1354219572170
Content-Type: text/plain; charset=ISO-8859-1
IMO it seems reasonable.
To summarize :
- It doesn't break existing code relying on the current assert() behavior
- It doesn't introduce a new macro, nor a new keyword (nor a namespaced
keyword :)
- The UB-assert cannot be enabled inadvertently in legacy code (NDEBUG + XNDEBUG
= compile time error)
- This proposal asks for very few modifications in the standard
--
------=_Part_411_25899392.1354219572170
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
IMO it seems reasonable.<div><br></div><div>To summarize :<div><div>- It do=
esn't break existing code relying on the current assert() behavior</div><di=
v>- It doesn't introduce a new macro, nor a new keyword (nor a namesp=
aced keyword :)</div><div>- The UB-assert cannot be enabled inadvertently i=
n legacy code (<span style=3D"line-height: 17px;">NDEBUG + </span><spa=
n style=3D"line-height: 17px;">XNDEBUG =3D compile time error)</span></div>=
<div><span style=3D"line-height: 17px;">- This proposal asks for very few m=
odifications in the standard</span></div><div><span style=3D"line-height: 1=
7px;"><br></span></div><div><span style=3D"line-height: 17px;"><br></span><=
/div></div></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_411_25899392.1354219572170--
.
Author: Lawrence Crowl <crowl@googlers.com>
Date: Thu, 29 Nov 2012 12:30:02 -0800
Raw View
On 11/29/12, Fr=E9d=E9ric TERRAZZONI <akryus@gmail.com> wrote:
> @Lawrence Crowl:
>
> The contract programming proposal is indeed better to deal with class
> invariants & pre/post-conditions. But it may not be always the best
> solution, especially if we are inside a function/method and we're
> asserting things about intermediary results.
>
> For instance, if at some point we want to benefit from automatic
> vectorization then we would be able to write :
>
> float *a,*b,*c;
> size_t n;
>
> // a,b,c are arrays of size n
>
> assert(c + n <=3D a || a + n <=3D c); //a doesn't alias c
> assert(c + n <=3D b || b + n <=3D c); //b doesn't alias c
>
> // vectorizable loop
> for(size_t i =3D 0 ; i < n ; i++)
> c[i] =3D a[i]*b[i];
>
> Notice that these two assertions doesn't prevent a and b to overlap
> (it is not possible to emulate this with the "restrict" keyword,
> because it's not expressive enough)
If a, b, c and n are parameters, then a precondition works. If they
are global variables visible to the caller, then a precondition
works. Otherwise, a function invariant works.
--=20
Lawrence Crowl
--=20
.
Author: Lawrence Crowl <crowl@googlers.com>
Date: Thu, 29 Nov 2012 12:38:21 -0800
Raw View
On 11/29/12, Jean-Marc Bourguet <jm.bourguet@gmail.com> wrote:
> 1/ Is this a standardization of a feature already provided by
> compilers?
>
> Until more indication that it would really be useful, I
> tend to think that if it was really useful for performance,
> compilers would have provided the feature in an implementation
> specific way and I don't remember having seen any. Well, gcc
> has __builtin_unreachable() but it seems designed for something
> else. I'd have expected a __builtin_assume if the feature was
> available.
The Sun compiler had something like performance assertions.
Great for benchmarks, but because it was Sun-specific and not
standard, many shops were not willing to use it.
GCC has __builtin_expect, which isn't quite the same thing. Again,
people tend to avoid it except in very small areas of code.
Before people are going to seriously use these mechanisms, they
need to be standard. The assert macro is inadequate in a lot of
ways, but everyone uses it precisely because it is standard.
Any mechanism in this space would be best if it could simultaneously
serve most of the needs of folks interested in correctness and
folks interested in performance.
> 2/ I'd provide this in a way not tied to an existing feature. It
> may be tempting, but I know projects which are using assert
> so that it fails when compiled without NDEBUG and providing an
> alternate execution path when compiled with NDEBUG.
--
Lawrence Crowl
--
.
Author: Marc <marc.glisse@gmail.com>
Date: Thu, 29 Nov 2012 12:57:58 -0800 (PST)
Raw View
------=_Part_381_27056732.1354222678546
Content-Type: text/plain; charset=ISO-8859-1
Hello,
having a way to provide some extra information to the compiler looks like a
good idea. However, I disagree with re-using assert for that. There are
many places with: assert(expensive_check_that_structure_is_valid()); where
you clearly don't want to run the check in release mode, and the compiler
wouldn't be able to remove the check if the preprocessor didn't do it (some
compiler magic might be possible so it doesn't actually execute the code,
but then it wouldn't be implementable in terms of the existing
__builtin_unreachable()).
--
------=_Part_381_27056732.1354222678546
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Hello,<br><br>having a way to provide some extra information to the compile=
r looks like a good idea. However, I disagree with re-using assert for that=
.. There are many places with: assert(expensive_check_that_structure_is_vali=
d()); where you clearly don't want to run the check in release mode, and th=
e compiler wouldn't be able to remove the check if the preprocessor didn't =
do it (some compiler magic might be possible so it doesn't actually execute=
the code, but then it wouldn't be implementable in terms of the existing _=
_builtin_unreachable()).<br>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_381_27056732.1354222678546--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Thu, 29 Nov 2012 13:08:28 -0800 (PST)
Raw View
------=_Part_367_925346.1354223308277
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu czwartek, 29 listopada 2012 21:57:58 UTC+1 u=BFytkownik Marc napisa=
=B3:
>
> Hello,
>
> having a way to provide some extra information to the compiler looks like=
=20
> a good idea. However, I disagree with re-using assert for that. There are=
=20
> many places with: assert(expensive_check_that_structure_is_valid()); wher=
e=20
> you clearly don't want to run the check in release mode, and the compiler=
=20
> wouldn't be able to remove the check if the preprocessor didn't do it (so=
me=20
> compiler magic might be possible so it doesn't actually execute the code,=
=20
> but then it wouldn't be implementable in terms of the existing=20
> __builtin_unreachable()).
>
In this "third" mode we are discussing, the predicate would not be=20
evaluated. The compiler is not forced to optimize the code, so it is not=20
forced to compile the code to execute the predicate. The compiler would=20
only optimize if it knew the condition would not be checked: this is=20
possible in two cases: (1) when someone types assert(false) or when someone=
=20
checks a condition that has already been checked:
if (x =3D=3D 0) {
//...
}
else {
assert(x !=3D 0);
}
One other example already shown in this thread:
int passengers =3D getPassengers();=20
switch( passengers % 2 ) {=20
case 1:=20
return handleOdd( passengers );=20
case 2:=20
return handleEven( passengers );=20
default:=20
assert(false);
}
Would allow the compiler to rearrange the code to:
switch( passengers % 2 ) {=20
case 1:=20
return handleOdd( passengers );=20
default:=20
return handleEven( passengers );
}=20
--=20
------=_Part_367_925346.1354223308277
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu czwartek, 29 listopada 2012 21:57:58 UTC+1 u=BFytkownik Marc=
napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hello,<br><br>havin=
g a way to provide some extra information to the compiler looks like a good=
idea. However, I disagree with re-using assert for that. There are many pl=
aces with: assert(expensive_check_that_<wbr>structure_is_valid()); where yo=
u clearly don't want to run the check in release mode, and the compiler wou=
ldn't be able to remove the check if the preprocessor didn't do it (some co=
mpiler magic might be possible so it doesn't actually execute the code, but=
then it wouldn't be implementable in terms of the existing __builtin_unrea=
chable()).<br></blockquote><div><br>In this "third" mode we are discussing,=
the predicate would not be evaluated. The compiler is not forced to optimi=
ze the code, so it is not forced to compile the code to execute the predica=
te. The compiler would only optimize if it knew the condition would not be =
checked: this is possible in two cases: (1) when someone types assert(false=
) or when someone checks a condition that has already been checked:<br><br>=
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); b=
order-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wo=
rd-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #008;" class=3D"styled-by-prettify">if</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">x </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"sty=
led-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">//...</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">else</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">assert</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">!=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br></span></div></code></div><br><br>One other example=
already shown in this thread:<br><br><pre><div style=3D"background-color:r=
gb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wid=
th:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">int</spa=
n><span style=3D"color:#000"> passengers </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> getPassengers</span><span style=3D"co=
lor:#660">();</span><span style=3D"color:#000"> <br></span><span style=3D"c=
olor:#008">switch</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000"> passengers </span><span style=3D"color:#660">%</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#066">2</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">)</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000=
"> <br></span><span style=3D"color:#008">case</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#066">1</span><span style=3D"color:#660">:=
</span><span style=3D"color:#000"> <br> </span><span style=3D"color:#=
008">return</span><span style=3D"color:#000"> handleOdd</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000"> passengers </span><span=
style=3D"color:#660">);</span><span style=3D"color:#000"> <br></span><span=
style=3D"color:#008">case</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#066">2</span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> <br> </span><span style=3D"color:#008">return</span>=
<span style=3D"color:#000"> handleEven</span><span style=3D"color:#660">(</=
span><span style=3D"color:#000"> passengers </span><span style=3D"color:#66=
0">);</span><span style=3D"color:#000"> <br></span><span style=3D"color:#00=
8">default</span><span style=3D"color:#660">:</span><span style=3D"color:#0=
00"> <br> </span><span style=3D"font-family:courier new,monospace"><s=
pan style=3D"color:#800">assert(false);</span><span style=3D"color:#000"><b=
r></span></span><span style=3D"color:#660">}</span></div></code></div><br><=
span style=3D"font-family:arial,sans-serif">Would allow the compiler to rea=
rrange the code to:<br><br></span><span style=3D"font-family:arial,sans-ser=
if"><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#008">switch</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000"> passengers </span><span style=3D"color:#660">%=
</span><span style=3D"color:#000"> </span><span style=3D"color:#066">2</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">)</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span st=
yle=3D"color:#000"> <br></span><span style=3D"color:#008">case</span><span =
style=3D"color:#000"> </span><span style=3D"color:#066">1</span><span style=
=3D"color:#660">:</span><span style=3D"color:#000"> <br> </span><span=
style=3D"color:#008">return</span><span style=3D"color:#000"> handleOdd</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#000"> passenge=
rs </span><span style=3D"color:#660">);</span><span style=3D"color:#000"> <=
br></span><span style=3D"color:#008">default</span><span style=3D"color:#66=
0">:</span><span style=3D"color:#000"> <br> </span><span style=3D"col=
or:#008">return</span><span style=3D"color:#000"> handleEven</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#000"> passengers </span><s=
pan style=3D"color:#660">);</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#660">}</span><span style=3D"color:#000"> </span></div></=
code></div></span></pre><br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_367_925346.1354223308277--
.
Author: =?UTF-8?Q?Fr=C3=A9d=C3=A9ric_TERRAZZONI?= <akryus@gmail.com>
Date: Thu, 29 Nov 2012 13:14:05 -0800 (PST)
Raw View
------=_Part_511_2965643.1354223645286
Content-Type: text/plain; charset=ISO-8859-1
@Lawrence Crowl: I read your link
(http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2006/n1962.html#block-invariants)
far too quickly. It seems that "block invariants" is closely related to
what we're talking about in that topic. I noticed you were involved in it,
so do you know what the SC think about introducing contract programming
(since 2006) ? (slightly off-topic question, but not totally)
--
------=_Part_511_2965643.1354223645286
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
@Lawrence Crowl: I read your link (http://www.open-std.org/JTC1/SC22/W=
G21/docs/papers/2006/n1962.html#block-invariants) far too quickly. It seems=
that "block invariants" is closely related to what we're talking about in =
that topic. I noticed you were involved in it, so do you know what the=
SC think about introducing contract programming (since 2006) ? (slightly o=
ff-topic question, but not totally)
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_511_2965643.1354223645286--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Fri, 30 Nov 2012 10:24:40 +0100
Raw View
On Fri, Nov 30, 2012 at 10:17 AM, Andrzej Krzemie=C5=84ski
<akrzemi1@gmail.com> wrote:
>> For even you'd want case 0, not case 2. For odd you'd generally want !=
=3D 0,
>> not =3D=3D 1.
>
>
> The example is supposed to show how an "improved" assert can allow certai=
n
> code rearrangements -- not to handle even or odd numbers.
I know, but having bugs in examples doesn't seem right.
>> IMO redefining assert (breaking backwards compatibility) just isn't an
>> option.
>
>
> In this discussion it was shown that this behavior can be implemented
> without breaking backwards compatibility: by introducing a third "mode" o=
f
> assertions (similar to NDEBUG).
What if a library header depending on the old assert() behaviour is
included in a program that has the new behaviour enabled?
Or code being copied between the two environments? The behaviour would
'silently' change.
What if I want to use both behaviours in the same program?
--=20
Olaf
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 30 Nov 2012 02:17:23 -0800 (PST)
Raw View
------=_Part_1358_28141768.1354270643262
Content-Type: text/plain; charset=ISO-8859-1
>
> > In this discussion it was shown that this behavior can be implemented
> > without breaking backwards compatibility: by introducing a third "mode"
> of
> > assertions (similar to NDEBUG).
>
> What if a library header depending on the old assert() behaviour is
> included in a program that has the new behaviour enabled?
>
I am not sure i understand the situation you are describing. (a short
example would help.) Normally you put an assert in a CPP file and it is
compiled separately and assertions work the way you configured them in your
implementation file. If a "new program" (i.e. a new translation unit)
defines macro XNDEBUG its asserts are optimized, but it does not affect the
behavior of asserts in other translation units. This is similar to the
current situation where you can define macro NDEBUG only in some
translation units and the behavior is well defined.
> Or code being copied between the two environments? The behaviour would
> 'silently' change.
>
I am sorry. I do not know what you mean here. I guess you say that the
"behaviour would 'slightly' change" if somewhere I decide to define macro
XNDEBU. But I do not see how it has anything to do with breaking backwards
compatibility. "Old porgrams" do not define macro XNDEBUG, so the upgrade
of the language with "improved" assert cannot affect them.
What if I want to use both behaviours in the same program?
>
You can request different behavior of assert even in the same TU. You can
do it even today:
#define NDEBUG
#include <cassert>
assert(false);
#undef NDEBUG
#include <cassert>
assert(false);
Regards,
&rzej
--
------=_Part_1358_28141768.1354270643262
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">> In this discussion it was=
shown that this behavior can be implemented
<br>> without breaking backwards compatibility: by introducing a third "=
mode" of
<br>> assertions (similar to NDEBUG).
<br>
<br>What if a library header depending on the old assert() behaviour is
<br>included in a program that has the new behaviour enabled?
<br></blockquote><div><br>I am not sure i understand the situation you are =
describing. (a short example would help.) Normally you put an assert in a C=
PP file and it is compiled separately and assertions work the way you confi=
gured them in your implementation file. If a "new program" (i.e. a new tran=
slation unit) defines macro XNDEBUG its asserts are optimized, but it does =
not affect the behavior of asserts in other translation units. This is simi=
lar to the current situation where you can define macro NDEBUG only in some=
translation units and the behavior is well defined.<br> <br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">Or code being copied between the =
two environments? The behaviour would
<br>'silently' change.
<br></blockquote><div><br>I am sorry. I do not know what you mean here. I g=
uess you say that the "behaviour would 'slightly' change" if somewhere I de=
cide to define macro XNDEBU. But I do not see how it has anything to do wit=
h breaking backwards compatibility. "Old porgrams" do not define macro XNDE=
BUG, so the upgrade of the language with "improved" assert cannot affect th=
em.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">What if I wan=
t to use both behaviours in the same program?
<br></blockquote><div><br>You can request different behavior of assert even=
in the same TU. You can do it even today:<br><br><div class=3D"prettyprint=
" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187=
, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><co=
de class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color=
: #800;" class=3D"styled-by-prettify">#define</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> NDEBUG<br></span><span style=3D"color: =
#800;" class=3D"styled-by-prettify">#include</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" clas=
s=3D"styled-by-prettify"><cassert></span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">false</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">#und=
ef</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> NDEBUG<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">#include</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #080;" class=3D"styled-by-prettify"><cassert></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">false</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span></div></code></div><br><br><br>Regards,<br>=
&rzej<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1358_28141768.1354270643262--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Fri, 30 Nov 2012 11:37:26 +0100
Raw View
On Fri, Nov 30, 2012 at 11:17 AM, Andrzej Krzemie=C5=84ski
<akrzemi1@gmail.com> wrote:
>> > In this discussion it was shown that this behavior can be implemented
>> > without breaking backwards compatibility: by introducing a third "mode=
"
>> > of
>> > assertions (similar to NDEBUG).
>>
>> What if a library header depending on the old assert() behaviour is
>> included in a program that has the new behaviour enabled?
>
>
> I am not sure i understand the situation you are describing. (a short
> example would help.) Normally you put an assert in a CPP file and it is
> compiled separately and assertions work the way you configured them in yo=
ur
> implementation file.
Some (Boost) libraries are header-only. They're not compiled separately.
They'd not be able to depend on any particular behaviour.
> If a "new program" (i.e. a new translation unit)
> defines macro XNDEBUG its asserts are optimized, but it does not affect t=
he
> behavior of asserts in other translation units. This is similar to the
> current situation where you can define macro NDEBUG only in some translat=
ion
> units and the behavior is well defined.
Is it?
If a class defines extra debug data members if NDEBUG isn't present
(think iterator validation for example) you might have ODR violations.
>>
>> Or code being copied between the two environments? The behaviour would
>> 'silently' change.
>
>
> I am sorry. I do not know what you mean here. I guess you say that the
> "behaviour would 'slightly' change" if somewhere I decide to define macro
> XNDEBU. But I do not see how it has anything to do with breaking backward=
s
> compatibility. "Old porgrams" do not define macro XNDEBUG, so the upgrade=
of
> the language with "improved" assert cannot affect them.
That's true, but the behaviour of identical code fragments would no
longer be identical.
For no-NDEBUG and NDEBUG that's also the case, but that distinction is
well known, you often have debug and release builds.
>> What if I want to use both behaviours in the same program?
>
>
> You can request different behavior of assert even in the same TU. You can=
do
> it even today:
>
> #define NDEBUG
> #include <cassert>
> assert(false);
>
> #undef NDEBUG
> #include <cassert>
> assert(false);
I know, but IMO that's seriously ugly.
I'd rather have assert(false); assume(false);
--=20
Olaf
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 30 Nov 2012 01:17:13 -0800 (PST)
Raw View
------=_Part_1304_18282395.1354267033216
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu pi=B1tek, 30 listopada 2012 10:09:51 UTC+1 u=BFytkownik Olaf van der=
=20
Spek napisa=B3:
>
> Op donderdag 29 november 2012 22:08:28 UTC+1 schreef Andrzej Krzemie=F1sk=
i=20
> het volgende:
>
>> One other example already shown in this thread:
>>
>> int passengers =3D getPassengers();=20
>> switch( passengers % 2 ) {=20
>> case 1:=20
>> return handleOdd( passengers );=20
>> case 2:=20
>> return handleEven( passengers );=20
>> default:=20
>> assert(false);
>> }
>>
>> Would allow the compiler to rearrange the code to:
>>
>> switch( passengers % 2 ) {=20
>> case 1:=20
>> return handleOdd( passengers );=20
>> default:=20
>> return handleEven( passengers );
>> }=20
>>
>> =20
> For even you'd want case 0, not case 2. For odd you'd generally want !=3D=
0,=20
> not =3D=3D 1.
>
The example is supposed to show how an "improved" assert can allow certain=
=20
code rearrangements -- not to handle even or odd numbers.=20
IMO redefining assert (breaking backwards compatibility) just isn't an=20
> option.
>
In this discussion it was shown that this behavior can be implemented=20
without breaking backwards compatibility: by introducing a third "mode" of=
=20
assertions (similar to NDEBUG).=20
--=20
------=_Part_1304_18282395.1354267033216
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=B1tek, 30 listopada 2012 10:09:51 UTC+1 u=BFytkownik Olaf=
van der Spek napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Op don=
derdag 29 november 2012 22:08:28 UTC+1 schreef Andrzej Krzemie=F1ski het vo=
lgende:<br><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:=
0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>One other example a=
lready shown in this thread:<br><br><pre><div style=3D"background-color:rgb=
(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-width=
:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">int</span>=
<span style=3D"color:#000"> passengers </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> getPassengers</span><span style=3D"co=
lor:#660">();</span><span style=3D"color:#000"> <br></span><span style=3D"c=
olor:#008">switch</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000"> passengers </span><span style=3D"color:#660">%</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#066">2</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">)</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000=
"> <br></span><span style=3D"color:#008">case</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#066">1</span><span style=3D"color:#660">:=
</span><span style=3D"color:#000"> <br> </span><span style=3D"color:#=
008">return</span><span style=3D"color:#000"> handleOdd</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000"> passengers </span><span=
style=3D"color:#660">);</span><span style=3D"color:#000"> <br></span><span=
style=3D"color:#008">case</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#066">2</span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> <br> </span><span style=3D"color:#008">return</span>=
<span style=3D"color:#000"> handleEven</span><span style=3D"color:#660">(</=
span><span style=3D"color:#000"> passengers </span><span style=3D"color:#66=
0">);</span><span style=3D"color:#000"> <br></span><span style=3D"color:#00=
8">default</span><span style=3D"color:#660">:</span><span style=3D"color:#0=
00"> <br> </span><span style=3D"font-family:courier new,monospace"><s=
pan style=3D"color:#800">assert(false);</span><span style=3D"color:#000"><b=
r></span></span><span style=3D"color:#660">}</span></div></code></div><br><=
span style=3D"font-family:arial,sans-serif">Would allow the compiler to rea=
rrange the code to:<br><br></span><span style=3D"font-family:arial,sans-ser=
if"><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#008">switch</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000"> passengers </span><span style=3D"color:#660">%=
</span><span style=3D"color:#000"> </span><span style=3D"color:#066">2</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">)</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span st=
yle=3D"color:#000"> <br></span><span style=3D"color:#008">case</span><span =
style=3D"color:#000"> </span><span style=3D"color:#066">1</span><span style=
=3D"color:#660">:</span><span style=3D"color:#000"> <br> </span><span=
style=3D"color:#008">return</span><span style=3D"color:#000"> handleOdd</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#000"> passenge=
rs </span><span style=3D"color:#660">);</span><span style=3D"color:#000"> <=
br></span><span style=3D"color:#008">default</span><span style=3D"color:#66=
0">:</span><span style=3D"color:#000"> <br> </span><span style=3D"col=
or:#008">return</span><span style=3D"color:#000"> handleEven</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#000"> passengers </span><s=
pan style=3D"color:#660">);</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#660">}</span><span style=3D"color:#000"> </span></div></=
code></div></span></pre></div></blockquote><div> </div><div>For even y=
ou'd want case 0, not case 2. For odd you'd generally want !=3D 0, not =3D=
=3D 1.</div></blockquote><div><br>The example is supposed to show how an "i=
mproved" assert can allow certain code rearrangements -- not to handle even=
or odd numbers. <br><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div>IMO redefining assert (breaking backwards compatibility) just isn't a=
n option.</div></blockquote><div><br>In this discussion it was shown that t=
his behavior can be implemented without breaking backwards compatibility: b=
y introducing a third "mode" of assertions (similar to NDEBUG). <br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1304_18282395.1354267033216--
.
Author: Lawrence Crowl <crowl@googlers.com>
Date: Thu, 29 Nov 2012 19:20:27 -0800
Raw View
On 11/29/12, Fr=E9d=E9ric TERRAZZONI <akryus@gmail.com> wrote:
> @Lawrence Crowl: I read your link
> (http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2006/n1962.html#block=
-invariants)
>
> far too quickly. It seems that "block invariants" is closely related to
> what we're talking about in that topic. I noticed you were involved in it=
,
> so do you know what the SC think about introducing contract programming
> (since 2006) ? (slightly off-topic question, but not totally)
The C++ committee decided not to pursue the feature for C++11.
Right now, there is no one working on it, and I do not have the time
to do so.
--=20
Lawrence Crowl
--=20
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Fri, 30 Nov 2012 01:04:30 -0800 (PST)
Raw View
------=_Part_928_14439035.1354266270266
Content-Type: text/plain; charset=ISO-8859-1
Op donderdag 29 november 2012 21:38:21 UTC+1 schreef Lawrence Crowl het
volgende:
> Before people are going to seriously use these mechanisms, they
> need to be standard. The assert macro is inadequate in a lot of
> ways, but everyone uses it precisely because it is standard.
>
In what ways is it inadequate (just curious)?
--
------=_Part_928_14439035.1354266270266
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Op donderdag 29 november 2012 21:38:21 UTC+1 schreef Lawrence Crowl het vol=
gende:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Before people are go=
ing to seriously use these mechanisms, they <br>need to be standard. &=
nbsp;The assert macro is inadequate in a lot of
<br>ways, but everyone uses it precisely because it is standard.
<br></blockquote><div><br></div><div>In what ways is it inadequate (just cu=
rious)?</div><div><br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_928_14439035.1354266270266--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Fri, 30 Nov 2012 01:09:51 -0800 (PST)
Raw View
------=_Part_14_9786783.1354266591307
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Op donderdag 29 november 2012 22:08:28 UTC+1 schreef Andrzej Krzemie=C5=84s=
ki=20
het volgende:
> One other example already shown in this thread:
>
> int passengers =3D getPassengers();=20
> switch( passengers % 2 ) {=20
> case 1:=20
> return handleOdd( passengers );=20
> case 2:=20
> return handleEven( passengers );=20
> default:=20
> assert(false);
> }
>
> Would allow the compiler to rearrange the code to:
>
> switch( passengers % 2 ) {=20
> case 1:=20
> return handleOdd( passengers );=20
> default:=20
> return handleEven( passengers );
> }=20
>
> =20
For even you'd want case 0, not case 2. For odd you'd generally want !=3D 0=
,=20
not =3D=3D 1.
IMO redefining assert (breaking backwards compatibility) just isn't an=20
option.
--=20
------=_Part_14_9786783.1354266591307
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Op donderdag 29 november 2012 22:08:28 UTC+1 schreef Andrzej Krzemie=C5=84s=
ki het volgende:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>One o=
ther example already shown in this thread:<br><br><pre><div style=3D"backgr=
ound-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:soli=
d;border-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#0=
08">int</span><span style=3D"color:#000"> passengers </span><span style=3D"=
color:#660">=3D</span><span style=3D"color:#000"> getPassengers</span><span=
style=3D"color:#660">();</span><span style=3D"color:#000"> <br></span><spa=
n style=3D"color:#008">switch</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000"> passengers </span><span style=3D"color:#660">%</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#066">2</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">)</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"> <br></span><span style=3D"color:#008">case</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#066">1</span><span style=3D=
"color:#660">:</span><span style=3D"color:#000"> <br> </span><span st=
yle=3D"color:#008">return</span><span style=3D"color:#000"> handleOdd</span=
><span style=3D"color:#660">(</span><span style=3D"color:#000"> passengers =
</span><span style=3D"color:#660">);</span><span style=3D"color:#000"> <br>=
</span><span style=3D"color:#008">case</span><span style=3D"color:#000"> </=
span><span style=3D"color:#066">2</span><span style=3D"color:#660">:</span>=
<span style=3D"color:#000"> <br> </span><span style=3D"color:#008">re=
turn</span><span style=3D"color:#000"> handleEven</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#000"> passengers </span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"> <br></span><span style=
=3D"color:#008">default</span><span style=3D"color:#660">:</span><span styl=
e=3D"color:#000"> <br> </span><span style=3D"font-family:courier new,=
monospace"><span style=3D"color:#800">assert(false);</span><span style=3D"c=
olor:#000"><br></span></span><span style=3D"color:#660">}</span></div></cod=
e></div><br><span style=3D"font-family:arial,sans-serif">Would allow the co=
mpiler to rearrange the code to:<br><br></span><span style=3D"font-family:a=
rial,sans-serif"><div style=3D"background-color:rgb(250,250,250);border-col=
or:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-wor=
d"><code><div><span style=3D"color:#008">switch</span><span style=3D"color:=
#660">(</span><span style=3D"color:#000"> passengers </span><span style=3D"=
color:#660">%</span><span style=3D"color:#000"> </span><span style=3D"color=
:#066">2</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</=
span><span style=3D"color:#000"> <br></span><span style=3D"color:#008">case=
</span><span style=3D"color:#000"> </span><span style=3D"color:#066">1</spa=
n><span style=3D"color:#660">:</span><span style=3D"color:#000"> <br> =
</span><span style=3D"color:#008">return</span><span style=3D"color:#000">=
handleOdd</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00"> passengers </span><span style=3D"color:#660">);</span><span style=3D"c=
olor:#000"> <br></span><span style=3D"color:#008">default</span><span style=
=3D"color:#660">:</span><span style=3D"color:#000"> <br> </span><span=
style=3D"color:#008">return</span><span style=3D"color:#000"> handleEven</=
span><span style=3D"color:#660">(</span><span style=3D"color:#000"> passeng=
ers </span><span style=3D"color:#660">);</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#660">}</span><span style=3D"color:#000"> </=
span></div></code></div></span></pre></div></blockquote><div> </div><d=
iv>For even you'd want case 0, not case 2. For odd you'd generally want !=
=3D 0, not =3D=3D 1.</div><div><br></div><div>IMO redefining assert (breaki=
ng backwards compatibility) just isn't an option.</div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_14_9786783.1354266591307--
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 30 Nov 2012 04:50:35 -0800 (PST)
Raw View
------=_Part_120_32531555.1354279835711
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu pi=B1tek, 30 listopada 2012 11:37:26 UTC+1 u=BFytkownik Olaf van der=
=20
Spek napisa=B3:
>
> On Fri, Nov 30, 2012 at 11:17 AM, Andrzej Krzemie=F1ski=20
> <akrz...@gmail.com <javascript:>> wrote:=20
> >> > In this discussion it was shown that this behavior can be implemente=
d=20
> >> > without breaking backwards compatibility: by introducing a third=20
> "mode"=20
> >> > of=20
> >> > assertions (similar to NDEBUG).=20
> >>=20
> >> What if a library header depending on the old assert() behaviour is=20
> >> included in a program that has the new behaviour enabled?=20
> >=20
> >=20
> > I am not sure i understand the situation you are describing. (a short=
=20
> > example would help.) Normally you put an assert in a CPP file and it is=
=20
> > compiled separately and assertions work the way you configured them in=
=20
> your=20
> > implementation file.=20
>
> Some (Boost) libraries are header-only. They're not compiled separately.=
=20
> They'd not be able to depend on any particular behaviour.=20
>
> > If a "new program" (i.e. a new translation unit)=20
> > defines macro XNDEBUG its asserts are optimized, but it does not affect=
=20
> the=20
> > behavior of asserts in other translation units. This is similar to the=
=20
> > current situation where you can define macro NDEBUG only in some=20
> translation=20
> > units and the behavior is well defined.=20
>
> Is it?=20
> If a class defines extra debug data members if NDEBUG isn't present=20
> (think iterator validation for example) you might have ODR violations.=20
>
While I acknowledge the problem you are describing, I believe the problem=
=20
is there already (because we have NDEBUG and non-NDEBUG) and template=20
library authors must already address it. The proposal would not make the=20
problem worse because "XNDEBUG" is similar to "NDEBUG": in either case you=
=20
do not want to add auxiliary members (unlike for non-NDEBUG).
> >>=20
> >> Or code being copied between the two environments? The behaviour would=
=20
> >> 'silently' change.=20
> >=20
> >=20
> > I am sorry. I do not know what you mean here. I guess you say that the=
=20
> > "behaviour would 'slightly' change" if somewhere I decide to define=20
> macro=20
> > XNDEBU. But I do not see how it has anything to do with breaking=20
> backwards=20
> > compatibility. "Old porgrams" do not define macro XNDEBUG, so the=20
> upgrade of=20
> > the language with "improved" assert cannot affect them.=20
>
> That's true, but the behaviour of identical code fragments would no=20
> longer be identical.=20
> For no-NDEBUG and NDEBUG that's also the case, but that distinction is=20
> well known, you often have debug and release builds.=20
>
I don't know. Perhaps I fail to imagine the situation you are describing=20
here. If you use release mode, you can define XNDEBUG in all yout TUs, and=
=20
I cannot imagine how it would cause ODR violation (assuming that your=20
asserts do not cause it already in C++03).
=20
>
> >> What if I want to use both behaviours in the same program?=20
> >=20
> >=20
> > You can request different behavior of assert even in the same TU. You=
=20
> can do=20
> > it even today:=20
> >=20
> > #define NDEBUG=20
> > #include <cassert>=20
> > assert(false);=20
> >=20
> > #undef NDEBUG=20
> > #include <cassert>=20
> > assert(false);=20
>
> I know, but IMO that's seriously ugly.=20
> I'd rather have assert(false); assume(false);=20
>
I would see the value of 'assume' only if I had to use both macros in one=
=20
function:
if (c1) {
assert(c2);
//...
} =20
else {
assume(c2);
//...
}
But it doesn't look realistic to me.
Regards,
&rzej
--=20
------=_Part_120_32531555.1354279835711
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=B1tek, 30 listopada 2012 11:37:26 UTC+1 u=BFytkownik Olaf=
van der Spek napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Fri=
, Nov 30, 2012 at 11:17 AM, Andrzej Krzemie=F1ski
<br><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
8IFQmtE2HQcJ">akrz...@gmail.com</a>> wrote:
<br>>> > In this discussion it was shown that this behavior can be=
implemented
<br>>> > without breaking backwards compatibility: by introducing =
a third "mode"
<br>>> > of
<br>>> > assertions (similar to NDEBUG).
<br>>>
<br>>> What if a library header depending on the old assert() behavio=
ur is
<br>>> included in a program that has the new behaviour enabled?
<br>>
<br>>
<br>> I am not sure i understand the situation you are describing. (a sh=
ort
<br>> example would help.) Normally you put an assert in a CPP file and =
it is
<br>> compiled separately and assertions work the way you configured the=
m in your
<br>> implementation file.
<br>
<br>Some (Boost) libraries are header-only. They're not compiled separately=
..
<br>They'd not be able to depend on any particular behaviour.
<br>
<br>> If a "new program" (i.e. a new translation unit)
<br>> defines macro XNDEBUG its asserts are optimized, but it does not a=
ffect the
<br>> behavior of asserts in other translation units. This is similar to=
the
<br>> current situation where you can define macro NDEBUG only in some t=
ranslation
<br>> units and the behavior is well defined.
<br>
<br>Is it?
<br>If a class defines extra debug data members if NDEBUG isn't present
<br>(think iterator validation for example) you might have ODR violations.
<br></blockquote><div><br>While I acknowledge the problem you are describin=
g, I believe the problem is there already (because we have NDEBUG and non-N=
DEBUG) and template library authors must already address it. The proposal w=
ould not make the problem worse because "XNDEBUG" is similar to "NDEBUG": i=
n either case you do not want to add auxiliary members (unlike for non-NDEB=
UG).<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>>>
<br>>> Or code being copied between the two environments? The behavio=
ur would
<br>>> 'silently' change.
<br>>
<br>>
<br>> I am sorry. I do not know what you mean here. I guess you say that=
the
<br>> "behaviour would 'slightly' change" if somewhere I decide to defin=
e macro
<br>> XNDEBU. But I do not see how it has anything to do with breaking b=
ackwards
<br>> compatibility. "Old porgrams" do not define macro XNDEBUG, so the =
upgrade of
<br>> the language with "improved" assert cannot affect them.
<br>
<br>That's true, but the behaviour of identical code fragments would no
<br>longer be identical.
<br>For no-NDEBUG and NDEBUG that's also the case, but that distinction is
<br>well known, you often have debug and release builds.
<br></blockquote><div><br>I don't know. Perhaps I fail to imagine the situa=
tion you are describing here. If you use release mode, you can define XNDEB=
UG in all yout TUs, and I cannot imagine how it would cause ODR violation (=
assuming that your asserts do not cause it already in C++03).<br> <br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>>> What if I want to use both behaviours in the same program?
<br>>
<br>>
<br>> You can request different behavior of assert even in the same TU. =
You can do
<br>> it even today:
<br>>
<br>> #define NDEBUG
<br>> #include <cassert>
<br>> assert(false);
<br>>
<br>> #undef NDEBUG
<br>> #include <cassert>
<br>> assert(false);
<br>
<br>I know, but IMO that's seriously ugly.
<br>I'd rather have assert(false); assume(false);
<br></blockquote><div><br>I would see the value of 'assume' only if I had t=
o use both macros in one function:<br><br><div class=3D"prettyprint" style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
border-style: solid; border-width: 1px; word-wrap: break-word;"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">if</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">c1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">c2</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br> </span><span style=3D"color: #800;" class=3D"=
styled-by-prettify">//...</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>else</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br> assume</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">c2</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br> </span><span style=3D"color: #=
800;" class=3D"styled-by-prettify">//...</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span></div></code></div><br>But it doesn't look realis=
tic to me.<br><br>Regards,<br>&rzej<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_120_32531555.1354279835711--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Fri, 30 Nov 2012 19:56:48 +0100
Raw View
On Fri, Nov 30, 2012 at 1:50 PM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.c=
om> wrote:
>> Is it?
>> If a class defines extra debug data members if NDEBUG isn't present
>> (think iterator validation for example) you might have ODR violations.
>
>
> While I acknowledge the problem you are describing, I believe the problem=
is
> there already (because we have NDEBUG and non-NDEBUG) and template librar=
y
> authors must already address it. The proposal would not make the problem
AFAIK this is addressed by compiling all files with the same defines
and settings.
> worse because "XNDEBUG" is similar to "NDEBUG": in either case you do not
> want to add auxiliary members (unlike for non-NDEBUG).
True, but what behavior should the template authors expect? The old or
the 'new'?
>> That's true, but the behaviour of identical code fragments would no
>> longer be identical.
>> For no-NDEBUG and NDEBUG that's also the case, but that distinction is
>> well known, you often have debug and release builds.
>
>
> I don't know. Perhaps I fail to imagine the situation you are describing
> here. If you use release mode, you can define XNDEBUG in all yout TUs, an=
d I
> cannot imagine how it would cause ODR violation (assuming that your asser=
ts
> do not cause it already in C++03).
This one isn't about ODR violations, it's about expectations for
someone that reads or writes the code.
>> > You can request different behavior of assert even in the same TU. You
>> > can do
>> > it even today:
>> >
>> > #define NDEBUG
>> > #include <cassert>
>> > assert(false);
>> >
>> > #undef NDEBUG
>> > #include <cassert>
>> > assert(false);
>>
>> I know, but IMO that's seriously ugly.
>> I'd rather have assert(false); assume(false);
>
>
> I would see the value of 'assume' only if I had to use both macros in one
> function:
>
> if (c1) {
> assert(c2);
> //...
> }
> else {
> assume(c2);
> //...
> }
>
> But it doesn't look realistic to me.
Why not?
--=20
Olaf
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 30 Nov 2012 12:30:02 -0800 (PST)
Raw View
------=_Part_1320_21060927.1354307402219
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu pi=B1tek, 30 listopada 2012 19:56:48 UTC+1 u=BFytkownik Olaf van der=
=20
Spek napisa=B3:
>
> On Fri, Nov 30, 2012 at 1:50 PM, Andrzej Krzemie=F1ski <akrz...@gmail.com=
<javascript:>>=20
> wrote:=20
> >> Is it?=20
> >> If a class defines extra debug data members if NDEBUG isn't present=20
> >> (think iterator validation for example) you might have ODR violations.=
=20
> >=20
> >=20
> > While I acknowledge the problem you are describing, I believe the=20
> problem is=20
> > there already (because we have NDEBUG and non-NDEBUG) and template=20
> library=20
> > authors must already address it. The proposal would not make the proble=
m=20
>
> AFAIK this is addressed by compiling all files with the same defines=20
> and settings.=20
>
> > worse because "XNDEBUG" is similar to "NDEBUG": in either case you do=
=20
> not=20
> > want to add auxiliary members (unlike for non-NDEBUG).=20
>
> True, but what behavior should the template authors expect? The old or=20
> the 'new'?=20
>
We are talking about assertions. Frederic proposes change in behavior only=
=20
in case assertion fails (well, technically, when the predicate in assertion=
=20
evaluates to false). Template authors should not expect an assertion to=20
fail. We put assertions and are sure that they do not fail. If suspect it=
=20
might fail, we fix the bug so that we are sure our assertion never fails.=
=20
With this attitude in mind, template authors do not have to care what=20
behavior they get if assertion fails, because they are confident it will=20
not happen. As Frederic pointed out, when your assertion fails in NDEBUG=20
mode you also get an undefined behavior, although at some "higher level of=
=20
abstraction".
>> That's true, but the behaviour of identical code fragments would no=20
> >> longer be identical.=20
> >> For no-NDEBUG and NDEBUG that's also the case, but that distinction is=
=20
> >> well known, you often have debug and release builds.=20
> >=20
> >=20
> > I don't know. Perhaps I fail to imagine the situation you are describin=
g=20
> > here. If you use release mode, you can define XNDEBUG in all yout TUs,=
=20
> and I=20
> > cannot imagine how it would cause ODR violation (assuming that your=20
> asserts=20
> > do not cause it already in C++03).=20
>
> This one isn't about ODR violations, it's about expectations for=20
> someone that reads or writes the code.
Perhaps it is just me, but my primary expectation of asserts is that they=
=20
should never fail. I plant lot of them and are confident (or, I believe)=20
that none of the asserts will ever fire. If one fires, especially in=20
production (either in NDEBUG or 'XNDEBUG' mode) what code is executed next=
=20
(the one I wrote or the one rearranged by the compiler) would be my least=
=20
concern. Because a failing assert indicates a bug in my code.=20
=20
> >> > You can request different behavior of assert even in the same TU. Yo=
u=20
> >> > can do=20
> >> > it even today:=20
> >> >=20
> >> > #define NDEBUG=20
> >> > #include <cassert>=20
> >> > assert(false);=20
> >> >=20
> >> > #undef NDEBUG=20
> >> > #include <cassert>=20
> >> > assert(false);=20
> >>=20
> >> I know, but IMO that's seriously ugly.=20
> >> I'd rather have assert(false); assume(false);=20
> >=20
> >=20
> > I would see the value of 'assume' only if I had to use both macros in=
=20
> one=20
> > function:=20
> >=20
> > if (c1) {=20
> > assert(c2);=20
> > //...=20
> > }=20
> > else {=20
> > assume(c2);=20
> > //...=20
> > }=20
> >=20
> > But it doesn't look realistic to me.=20
>
> Why not?=20
>
I cannot even imagine what that means, that you 'assert' one thing and you=
=20
'assume' another. Now if I imagine a guy that is only learning C++ and he=
=20
is told that he sometimes has to assert something in the code, sometimes he=
=20
has to assume something, and sometimes he has to both assert and assume.=20
Wouldn't that be too complicated? The way I understand assertions (but=20
perhaps this is only me)is that you express something condition that you=20
expect never to be true at this point. What the compiler does with it is=20
secondary. I.e., in ideal world (where the halting problem is resolved) a=
=20
compiler would verify that my assertions ever fail. Since it cannot do it,=
=20
there is no good action to be taken, so we are given option: check and=20
terminate, ignore (for performance reasons), ignore, but check syntax (this=
=20
option is not available). Further optimizations are just another option in=
=20
the set.
In other words, when I plant an assert, in my mind it means "condition C=20
will never happen"; it does not mean "when NDEBUG is not defined then=20
evaluate C and if it fails call abort; otherwise do nothing". Assert is a=
=20
tool from "declarative" programming rather than "imperative" programming.=
=20
But again, this is probably only my point of view.
Regards,
&rzej
--=20
------=_Part_1320_21060927.1354307402219
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu pi=B1tek, 30 listopada 2012 19:56:48 UTC+1 u=BFytkownik Olaf=
van der Spek napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Fri=
, Nov 30, 2012 at 1:50 PM, Andrzej Krzemie=F1ski <<a href=3D"javascript:=
" target=3D"_blank" gdf-obfuscated-mailto=3D"kPCZmGSIisAJ">akrz...@gmail.co=
m</a>> wrote:
<br>>> Is it?
<br>>> If a class defines extra debug data members if NDEBUG isn't pr=
esent
<br>>> (think iterator validation for example) you might have ODR vio=
lations.
<br>>
<br>>
<br>> While I acknowledge the problem you are describing, I believe the =
problem is
<br>> there already (because we have NDEBUG and non-NDEBUG) and template=
library
<br>> authors must already address it. The proposal would not make the p=
roblem
<br>
<br>AFAIK this is addressed by compiling all files with the same defines
<br>and settings.
<br>
<br>> worse because "XNDEBUG" is similar to "NDEBUG": in either case you=
do not
<br>> want to add auxiliary members (unlike for non-NDEBUG).
<br>
<br>True, but what behavior should the template authors expect? The old or
<br>the 'new'?
<br></blockquote><div><br>We are talking about assertions. Frederic propose=
s change in behavior only in case assertion fails (well, technically, when =
the predicate in assertion evaluates to false). Template authors should not=
expect an assertion to fail. We put assertions and are sure that they do n=
ot fail. If suspect it might fail, we fix the bug so that we are sure our a=
ssertion never fails. With this attitude in mind, template authors do not h=
ave to care what behavior they get if assertion fails, because they are con=
fident it will not happen. As Frederic pointed out, when your assertion fai=
ls in NDEBUG mode you also get an undefined behavior, although at some "hig=
her level of abstraction".<br><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;">>> That's true, but the behaviour of identical code fragmen=
ts would no
<br>>> longer be identical.
<br>>> For no-NDEBUG and NDEBUG that's also the case, but that distin=
ction is
<br>>> well known, you often have debug and release builds.
<br>>
<br>>
<br>> I don't know. Perhaps I fail to imagine the situation you are desc=
ribing
<br>> here. If you use release mode, you can define XNDEBUG in all yout =
TUs, and I
<br>> cannot imagine how it would cause ODR violation (assuming that you=
r asserts
<br>> do not cause it already in C++03).
<br>
<br>This one isn't about ODR violations, it's about expectations for
<br>someone that reads or writes the code.</blockquote><div><br>Perhaps it =
is just me, but my primary expectation of asserts is that they should never=
fail. I plant lot of them and are confident (or, I believe) that none of t=
he asserts will ever fire. If one fires, especially in production (either i=
n NDEBUG or 'XNDEBUG' mode) what code is executed next (the one I wrote or =
the one rearranged by the compiler) would be my least concern. Because a fa=
iling assert indicates a bug in my code. <br></div><div> <br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">>> > You can request dif=
ferent behavior of assert even in the same TU. You
<br>>> > can do
<br>>> > it even today:
<br>>> >
<br>>> > #define NDEBUG
<br>>> > #include <cassert>
<br>>> > assert(false);
<br>>> >
<br>>> > #undef NDEBUG
<br>>> > #include <cassert>
<br>>> > assert(false);
<br>>>
<br>>> I know, but IMO that's seriously ugly.
<br>>> I'd rather have assert(false); assume(false);
<br>>
<br>>
<br>> I would see the value of 'assume' only if I had to use both macros=
in one
<br>> function:
<br>>
<br>> if (c1) {
<br>> assert(c2);
<br>> //...
<br>> }
<br>> else {
<br>> assume(c2);
<br>> //...
<br>> }
<br>>
<br>> But it doesn't look realistic to me.
<br>
<br>Why not?
<br></blockquote><div><br>I cannot even imagine what that means, that you '=
assert' one thing and you 'assume' another. Now if I imagine a guy that is =
only learning C++ and he is told that he sometimes has to assert something =
in the code, sometimes he has to assume something, and sometimes he has to =
both assert and assume. Wouldn't that be too complicated? The way I underst=
and assertions (but perhaps this is only me)is that you express something c=
ondition that you expect never to be true at this point. What the compiler =
does with it is secondary. I.e., in ideal world (where the halting problem =
is resolved) a compiler would verify that my assertions ever fail. Since it=
cannot do it, there is no good action to be taken, so we are given option:=
check and terminate, ignore (for performance reasons), ignore, but check s=
yntax (this option is not available). Further optimizations are just anothe=
r option in the set.<br><br>In other words, when I plant an assert, in my m=
ind it means "condition C will never happen"; it does not mean "when NDEBUG=
is not defined then evaluate C and if it fails call abort; otherwise do no=
thing". Assert is a tool from "declarative" programming rather than "impera=
tive" programming. But again, this is probably only my point of view.<br><b=
r>Regards,<br>&rzej<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1320_21060927.1354307402219--
.
Author: Lawrence Crowl <crowl@googlers.com>
Date: Fri, 30 Nov 2012 13:12:22 -0800
Raw View
On 11/30/12, Olaf van der Spek <olafvdspek@gmail.com> wrote:
> Op 29 november 2012 schreef Lawrence Crowl het volgende:
> > Before people are going to seriously use these mechanisms, they
> > need to be standard. The assert macro is inadequate in a lot of
> > ways, but everyone uses it precisely because it is standard.
>
> In what ways is it inadequate (just curious)?
Assert has many uses, and having only one name makes it hard to
enable assert for only some uses.
One of the uses is precondition checking. Unfortunately, the assert
is in the body of the function and unavailable to the compiler
at the call site, which means that the compiler cannot eliminate
provably true assertions.
--
Lawrence Crowl
--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sat, 1 Dec 2012 13:31:39 +0100
Raw View
On Fri, Nov 30, 2012 at 9:30 PM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.c=
om> wrote:
>> True, but what behavior should the template authors expect? The old or
>> the 'new'?
>
>
> We are talking about assertions. Frederic proposes change in behavior onl=
y
> in case assertion fails (well, technically, when the predicate in asserti=
on
> evaluates to false). Template authors should not expect an assertion to
> fail. We put assertions and are sure that they do not fail. If suspect it
Who is we? ;)
True, assertions aren't expected to fail, but they're not guaranteed
to halt the program either. The code that follows might depend on that
last property.
I think examples were posted already.
> might fail, we fix the bug so that we are sure our assertion never fails.
> With this attitude in mind, template authors do not have to care what
> behavior they get if assertion fails, because they are confident it will =
not
> happen. As Frederic pointed out, when your assertion fails in NDEBUG mode
> you also get an undefined behavior, although at some "higher level of
> abstraction".
I don't think that's always true.
>> This one isn't about ODR violations, it's about expectations for
>> someone that reads or writes the code.
>
>
> Perhaps it is just me, but my primary expectation of asserts is that they
> should never fail. I plant lot of them and are confident (or, I believe)
> that none of the asserts will ever fire. If one fires, especially in
> production (either in NDEBUG or 'XNDEBUG' mode) what code is executed nex=
t
> (the one I wrote or the one rearranged by the compiler) would be my least
> concern. Because a failing assert indicates a bug in my code.
Again, I think that's just one use case of asserts.
>> > But it doesn't look realistic to me.
>>
>> Why not?
>
>
> I cannot even imagine what that means, that you 'assert' one thing and yo=
u
> 'assume' another. Now if I imagine a guy that is only learning C++ and he=
is
> told that he sometimes has to assert something in the code, sometimes he =
has
> to assume something, and sometimes he has to both assert and assume.
> Wouldn't that be too complicated? The way I understand assertions (but
If you don't need the current behavior of assert, you don't need to
use/teach it, do you?
> perhaps this is only me)is that you express something condition that you
> expect never to be true at this point. What the compiler does with it is
> secondary. I.e., in ideal world (where the halting problem is resolved) a
> compiler would verify that my assertions ever fail. Since it cannot do it=
,
> there is no good action to be taken, so we are given option: check and
> terminate, ignore (for performance reasons), ignore, but check syntax (th=
is
> option is not available). Further optimizations are just another option i=
n
> the set.
>
> In other words, when I plant an assert, in my mind it means "condition C
> will never happen"; it does not mean "when NDEBUG is not defined then
> evaluate C and if it fails call abort; otherwise do nothing". Assert is a
> tool from "declarative" programming rather than "imperative" programming.
> But again, this is probably only my point of view.
That's true for some of my asserts as well, but not for all of them.
--=20
Olaf
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Sat, 1 Dec 2012 05:52:38 -0800 (PST)
Raw View
------=_Part_92_18949530.1354369958794
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
W dniu sobota, 1 grudnia 2012 13:31:39 UTC+1 u=BFytkownik Olaf van der Spek=
=20
napisa=B3:
>
> On Fri, Nov 30, 2012 at 9:30 PM, Andrzej Krzemie=F1ski <akrz...@gmail.com=
<javascript:>>=20
> wrote:=20
> >> True, but what behavior should the template authors expect? The old or=
=20
> >> the 'new'?=20
> >=20
> >=20
> > We are talking about assertions. Frederic proposes change in behavior=
=20
> only=20
> > in case assertion fails (well, technically, when the predicate in=20
> assertion=20
> > evaluates to false). Template authors should not expect an assertion to=
=20
> > fail. We put assertions and are sure that they do not fail. If suspect=
=20
> it=20
>
> Who is we? ;)=20
> True, assertions aren't expected to fail, but they're not guaranteed=20
> to halt the program either. The code that follows might depend on that=20
> last property.=20
> I think examples were posted already.=20
>
"The code that follows might depend on" the property that assertions "are=
=20
not guaranteed to halt the program"? This is how I understood your=20
sentence. Is this it right? Do you mean the situation like this:
assert(p !=3D NULL);=20
if (p =3D=3D NULL)=20
return false; // or etc=20
I.e., "either abort or return"? Then I see what you mean. But is this a=20
"valid" use of assertion? Why do you assert if you know what to do in such=
=20
case?
=20
>
> > might fail, we fix the bug so that we are sure our assertion never=20
> fails.=20
> > With this attitude in mind, template authors do not have to care what=
=20
> > behavior they get if assertion fails, because they are confident it wil=
l=20
> not=20
> > happen. As Frederic pointed out, when your assertion fails in NDEBUG=20
> mode=20
> > you also get an undefined behavior, although at some "higher level of=
=20
> > abstraction".=20
>
> I don't think that's always true.=20
>
What are the other cases? "abort or return" as the one above, or anything=
=20
else?
> >> This one isn't about ODR violations, it's about expectations for=20
> >> someone that reads or writes the code.=20
> >=20
> >=20
> > Perhaps it is just me, but my primary expectation of asserts is that=20
> they=20
> > should never fail. I plant lot of them and are confident (or, I believe=
)=20
> > that none of the asserts will ever fire. If one fires, especially in=20
> > production (either in NDEBUG or 'XNDEBUG' mode) what code is executed=
=20
> next=20
> > (the one I wrote or the one rearranged by the compiler) would be my=20
> least=20
> > concern. Because a failing assert indicates a bug in my code.=20
>
> Again, I think that's just one use case of asserts.
What are the others?=20
>> > But it doesn't look realistic to me.=20
> >>=20
> >> Why not?=20
> >=20
> >=20
> > I cannot even imagine what that means, that you 'assert' one thing and=
=20
> you=20
> > 'assume' another. Now if I imagine a guy that is only learning C++ and=
=20
> he is=20
> > told that he sometimes has to assert something in the code, sometimes h=
e=20
> has=20
> > to assume something, and sometimes he has to both assert and assume.=20
> > Wouldn't that be too complicated? The way I understand assertions (but=
=20
>
> If you don't need the current behavior of assert, you don't need to=20
> use/teach it, do you?=20
>
I do not understand what you are saying here. I need assertions to express=
=20
my understanding of the code and I accept the "behavior" (abort or no-op).=
=20
And I need to use the tool.
> > perhaps this is only me)is that you express something condition that yo=
u=20
> > expect never to be true at this point. What the compiler does with it i=
s=20
> > secondary. I.e., in ideal world (where the halting problem is resolved)=
=20
> a=20
> > compiler would verify that my assertions ever fail. Since it cannot do=
=20
> it,=20
> > there is no good action to be taken, so we are given option: check and=
=20
> > terminate, ignore (for performance reasons), ignore, but check syntax=
=20
> (this=20
> > option is not available). Further optimizations are just another option=
=20
> in=20
> > the set.=20
> >=20
> > In other words, when I plant an assert, in my mind it means "condition =
C=20
> > will never happen"; it does not mean "when NDEBUG is not defined then=
=20
> > evaluate C and if it fails call abort; otherwise do nothing". Assert is=
=20
> a=20
> > tool from "declarative" programming rather than "imperative"=20
> programming.=20
> > But again, this is probably only my point of view.=20
>
> That's true for some of my asserts as well, but not for all of them.=20
>
In a couple of places you indicated that there are other uses of assertions=
=20
(then to indicate a bug). What are they?
Regards,
&rzej=20
--=20
------=_Part_92_18949530.1354369958794
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable
<br><br>W dniu sobota, 1 grudnia 2012 13:31:39 UTC+1 u=BFytkownik Olaf van =
der Spek napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Fri, Nov=
30, 2012 at 9:30 PM, Andrzej Krzemie=F1ski <<a href=3D"javascript:" tar=
get=3D"_blank" gdf-obfuscated-mailto=3D"hHIfhk0xO14J">akrz...@gmail.com</a>=
> wrote:
<br>>> True, but what behavior should the template authors expect? Th=
e old or
<br>>> the 'new'?
<br>>
<br>>
<br>> We are talking about assertions. Frederic proposes change in behav=
ior only
<br>> in case assertion fails (well, technically, when the predicate in =
assertion
<br>> evaluates to false). Template authors should not expect an asserti=
on to
<br>> fail. We put assertions and are sure that they do not fail. If sus=
pect it
<br>
<br>Who is we? ;)
<br>True, assertions aren't expected to fail, but they're not guaranteed
<br>to halt the program either. The code that follows might depend on that
<br>last property.
<br>I think examples were posted already.
<br></blockquote><div><br>"The code that follows might depend on" the prope=
rty that assertions "are not guaranteed to halt the program"? This is how I=
understood your sentence. Is this it right? Do you mean the situation like=
this:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 25=
0, 250); border-color: rgb(187, 187, 187); border-style: solid; border-widt=
h: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"s=
ubprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">as=
sert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">p </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">!=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> NULL</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> <br></span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">if</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">p </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> NULL</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> <br> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">false</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" =
class=3D"styled-by-prettify">// or etc </span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span></div></code></div><br>I.e., "eithe=
r abort or return"? Then I see what you mean. But is this a "valid" use of =
assertion? Why do you assert if you know what to do in such case?<br> =
<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>> might fail, we fix the bug so that we are sure our assertion never=
fails.
<br>> With this attitude in mind, template authors do not have to care w=
hat
<br>> behavior they get if assertion fails, because they are confident i=
t will not
<br>> happen. As Frederic pointed out, when your assertion fails in NDEB=
UG mode
<br>> you also get an undefined behavior, although at some "higher level=
of
<br>> abstraction".
<br>
<br>I don't think that's always true.
<br></blockquote><div><br>What are the other cases? "abort or return" as th=
e one above, or anything else?<br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;">
<br>>> This one isn't about ODR violations, it's about expectations f=
or
<br>>> someone that reads or writes the code.
<br>>
<br>>
<br>> Perhaps it is just me, but my primary expectation of asserts is th=
at they
<br>> should never fail. I plant lot of them and are confident (or, I be=
lieve)
<br>> that none of the asserts will ever fire. If one fires, especially =
in
<br>> production (either in NDEBUG or 'XNDEBUG' mode) what code is execu=
ted next
<br>> (the one I wrote or the one rearranged by the compiler) would be m=
y least
<br>> concern. Because a failing assert indicates a bug in my code.
<br>
<br>Again, I think that's just one use case of asserts.</blockquote><div><b=
r>What are the others? <br><br><br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;">>> > But it doesn't look realistic to me.
<br>>>
<br>>> Why not?
<br>>
<br>>
<br>> I cannot even imagine what that means, that you 'assert' one thing=
and you
<br>> 'assume' another. Now if I imagine a guy that is only learning C++=
and he is
<br>> told that he sometimes has to assert something in the code, someti=
mes he has
<br>> to assume something, and sometimes he has to both assert and assum=
e.
<br>> Wouldn't that be too complicated? The way I understand assertions =
(but
<br>
<br>If you don't need the current behavior of assert, you don't need to
<br>use/teach it, do you?
<br></blockquote><div><br>I do not understand what you are saying here. I n=
eed assertions to express my understanding of the code and I accept the "be=
havior" (abort or no-op). And I need to use the tool.<br><br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;">
<br>> perhaps this is only me)is that you express something condition th=
at you
<br>> expect never to be true at this point. What the compiler does with=
it is
<br>> secondary. I.e., in ideal world (where the halting problem is reso=
lved) a
<br>> compiler would verify that my assertions ever fail. Since it canno=
t do it,
<br>> there is no good action to be taken, so we are given option: check=
and
<br>> terminate, ignore (for performance reasons), ignore, but check syn=
tax (this
<br>> option is not available). Further optimizations are just another o=
ption in
<br>> the set.
<br>>
<br>> In other words, when I plant an assert, in my mind it means "condi=
tion C
<br>> will never happen"; it does not mean "when NDEBUG is not defined t=
hen
<br>> evaluate C and if it fails call abort; otherwise do nothing". Asse=
rt is a
<br>> tool from "declarative" programming rather than "imperative" progr=
amming.
<br>> But again, this is probably only my point of view.
<br>
<br>That's true for some of my asserts as well, but not for all of them.
<br></blockquote><div><br>In a couple of places you indicated that there ar=
e other uses of assertions (then to indicate a bug). What are they?<br><br>=
Regards,<br>&rzej <br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_92_18949530.1354369958794--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sun, 2 Dec 2012 16:31:50 +0100
Raw View
On Sat, Dec 1, 2012 at 2:52 PM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.co=
m> wrote:
>> True, assertions aren't expected to fail, but they're not guaranteed
>> to halt the program either. The code that follows might depend on that
>> last property.
>> I think examples were posted already.
>
>
> "The code that follows might depend on" the property that assertions "are
> not guaranteed to halt the program"? This is how I understood your senten=
ce.
> Is this it right?
Kinda. The compiler can't assume the assertion is true, because assert
isn't guaranteed to abort if it's not.
If assert was guaranteed to abort (basically like my proposed assure),
it could make that assumption.
> Do you mean the situation like this:
> assert(p !=3D NULL);
> if (p =3D=3D NULL)
> return false; // or etc
Yep
> I.e., "either abort or return"? Then I see what you mean. But is this a
> "valid" use of assertion?
Don't know, but it is used like that in existing code.
> Why do you assert if you know what to do in such
> case?
Maybe you want the debugger to break there.
Maybe the code that follows kinda silently ignores the error, but
you'd still want to know about it in debug builds.
> What are the other cases? "abort or return" as the one above, or anything
> else?
Mostly abort or deal with it like above.
Olaf
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Mon, 3 Dec 2012 01:06:25 -0800 (PST)
Raw View
------=_Part_657_22734212.1354525585613
Content-Type: text/plain; charset=ISO-8859-1
> >> True, assertions aren't expected to fail, but they're not guaranteed
> >> to halt the program either. The code that follows might depend on that
> >> last property.
> >> I think examples were posted already.
> >
> >
> > "The code that follows might depend on" the property that assertions
> "are
> > not guaranteed to halt the program"? This is how I understood your
> sentence.
> > Is this it right?
>
> Kinda. The compiler can't assume the assertion is true, because assert
> isn't guaranteed to abort if it's not.
> If assert was guaranteed to abort (basically like my proposed assure),
> it could make that assumption.
>
> > Do you mean the situation like this:
> > assert(p != NULL);
> > if (p == NULL)
> > return false; // or etc
>
> Yep
>
> > I.e., "either abort or return"? Then I see what you mean. But is this a
> > "valid" use of assertion?
>
> Don't know, but it is used like that in existing code.
>
> > Why do you assert if you know what to do in such
> > case?
>
> Maybe you want the debugger to break there.
> Maybe the code that follows kinda silently ignores the error, but
> you'd still want to know about it in debug builds.
>
OK, now I understand the concern. However, I wonder if this "XNDEBUG"
behavior would really affect anyone. If you use assertions in this way
"abort of handle" in your own code (i.e., not in a library), you will not
be hurt, because you control the "mode" of assertions. If you are writing a
library that does not require the distribution of source code (i.e., a
non-template library), again, you are in control of the assertion mode.
Only when you ship a "template library", you might get hit. But would you
do this "abort of handle" trick in a template library, where the code is
exposed to the clients? It would be like you (the library author) were
imposing certain diagnostic measures on the clients, that clients may not
wish. Do you know any template library that exposes the behavior "abort of
handle"?
Regards,
&rzej
--
------=_Part_657_22734212.1354525585613
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">>> True, assertions =
aren't expected to fail, but they're not guaranteed
<br>>> to halt the program either. The code that follows might depend=
on that
<br>>> last property.
<br>>> I think examples were posted already.
<br>>
<br>>
<br>> "The code that follows might depend on" the property that assertio=
ns "are
<br>> not guaranteed to halt the program"? This is how I understood your=
sentence.
<br>> Is this it right?
<br>
<br>Kinda. The compiler can't assume the assertion is true, because assert
<br>isn't guaranteed to abort if it's not.
<br>If assert was guaranteed to abort (basically like my proposed assure),
<br>it could make that assumption.
<br>
<br>> Do you mean the situation like this:
<br>> assert(p !=3D NULL);
<br>> if (p =3D=3D NULL)
<br>> return false; // or etc
<br>
<br>Yep
<br>
<br>> I.e., "either abort or return"? Then I see what you mean. But is t=
his a
<br>> "valid" use of assertion?
<br>
<br>Don't know, but it is used like that in existing code.
<br>
<br>> Why do you assert if you know what to do in such
<br>> case?
<br>
<br>Maybe you want the debugger to break there.
<br>Maybe the code that follows kinda silently ignores the error, but
<br>you'd still want to know about it in debug builds.
<br></blockquote><div><br>OK, now I understand the concern. However, I wond=
er if this "XNDEBUG" behavior would really affect anyone. If you use assert=
ions in this way "abort of handle" in your own code (i.e., not in a library=
), you will not be hurt, because you control the "mode" of assertions. If y=
ou are writing a library that does not require the distribution of source c=
ode (i.e., a non-template library), again, you are in control of the assert=
ion mode. Only when you ship a "template library", you might get hit. But w=
ould you do this "abort of handle" trick in a template library, where the c=
ode is exposed to the clients? It would be like you (the library author) we=
re imposing certain diagnostic measures on the clients, that clients may no=
t wish. Do you know any template library that exposes the behavior "abort o=
f handle"?<br><br>Regards,<br>&rzej<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_657_22734212.1354525585613--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Mon, 3 Dec 2012 23:22:20 +0100
Raw View
On Mon, Dec 3, 2012 at 10:06 AM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.c=
om> wrote:
>> > Why do you assert if you know what to do in such
>> > case?
>>
>> Maybe you want the debugger to break there.
>> Maybe the code that follows kinda silently ignores the error, but
>> you'd still want to know about it in debug builds.
>
>
> OK, now I understand the concern. However, I wonder if this "XNDEBUG"
> behavior would really affect anyone. If you use assertions in this way
> "abort of handle" in your own code (i.e., not in a library), you will not=
be
> hurt, because you control the "mode" of assertions. If you are writing a
> library that does not require the distribution of source code (i.e., a
> non-template library), again, you are in control of the assertion mode. O=
nly
> when you ship a "template library", you might get hit.
Header-only code isn't always template code.
> But would you do this
> "abort of handle" trick in a template library, where the code is exposed =
to
> the clients? It would be like you (the library author) were imposing cert=
ain
> diagnostic measures on the clients, that clients may not wish. Do you kno=
w
> any template library that exposes the behavior "abort of handle"?
No, but then again I don't really pay attention to that code.
One example from my own code though:
http://code.google.com/p/xbt/source/browse/trunk/xbt/misc/xbt/to_array.h
--=20
Olaf
--=20
.
Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Thu, 6 Dec 2012 01:08:22 -0800 (PST)
Raw View
------=_Part_335_32050639.1354784902387
Content-Type: text/plain; charset=ISO-8859-1
> > But would you do this
> > "abort of handle" trick in a template library, where the code is exposed
> to
> > the clients? It would be like you (the library author) were imposing
> certain
> > diagnostic measures on the clients, that clients may not wish. Do you
> know
> > any template library that exposes the behavior "abort of handle"?
>
> No, but then again I don't really pay attention to that code.
>
> One example from my own code though:
> http://code.google.com/p/xbt/source/browse/trunk/xbt/misc/xbt/to_array.h
>
Thanks for the example. It looks like you are using an assert to express a
precondition. How do you specify the contract for your function to_array?
Do you say "Requires that input range is of the same size as the requested
array's size; returns all elements from range in array".
Or do you say "Requires nothing; if input range is of the same size then
returns all elements from range in array, otherwise returns an array of
zeros"
?
Regards,
&rzej
--
------=_Part_335_32050639.1354784902387
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<iframe style=3D"padding: 0px; position: absolute; top: 0px; left: 0p=
x; width: 726px; height: 200px; visibility: hidden;" frameborder=3D"0"></if=
rame><br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">> But would you do=
this
<br>> "abort of handle" trick in a template library, where the code is e=
xposed to
<br>> the clients? It would be like you (the library author) were imposi=
ng certain
<br>> diagnostic measures on the clients, that clients may not wish. Do =
you know
<br>> any template library that exposes the behavior "abort of handle"?
<br>
<br>No, but then again I don't really pay attention to that code.
<br>
<br>One example from my own code though:
<br><a href=3D"http://code.google.com/p/xbt/source/browse/trunk/xbt/misc/xb=
t/to_array.h" target=3D"_blank">http://code.google.com/p/xbt/<wbr>source/br=
owse/trunk/xbt/misc/<wbr>xbt/to_array.h</a>
<br></blockquote><div><br>Thanks for the example. It looks like you are usi=
ng an assert to express a precondition. How do you specify the contract for=
your function to_array?<br>Do you say "Requires that input range is of the=
same size as the requested array's size; returns all elements from range i=
n array".<br>Or do you say "Requires nothing; if input range is of the same=
size then returns all elements from range in array, otherwise returns an a=
rray of zeros"<br>?<br><br>Regards,<br>&rzej<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_335_32050639.1354784902387--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Thu, 6 Dec 2012 14:10:40 +0100
Raw View
On Thu, Dec 6, 2012 at 10:08 AM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.c=
om> wrote:
>> No, but then again I don't really pay attention to that code.
>>
>> One example from my own code though:
>> http://code.google.com/p/xbt/source/browse/trunk/xbt/misc/xbt/to_array.h
>
>
> Thanks for the example. It looks like you are using an assert to express =
a
> precondition. How do you specify the contract for your function to_array?
I don't.
> Do you say "Requires that input range is of the same size as the requeste=
d
> array's size; returns all elements from range in array".
> Or do you say "Requires nothing; if input range is of the same size then
> returns all elements from range in array, otherwise returns an array of
> zeros"
Probably the former, although I'm struggling with this function.
--=20
Olaf
--=20
.