assumeSafeAppend and purity

Steven Schveighoffer schveiguy at
Mon Feb 6 18:28:49 PST 2012

On Mon, 06 Feb 2012 21:18:21 -0500, Vladimir Panteleev  
<vladimir at> wrote:

> On Tuesday, 7 February 2012 at 02:02:22 UTC, Jonathan M Davis wrote:
>> On Tuesday, February 07, 2012 02:54:40 Vladimir Panteleev wrote:
>>> On Tuesday, 7 February 2012 at 01:47:12 UTC, Jonathan M Davis
>>>  wrote:
>>> > At present, assumeSafeAppend isn't pure - nor is capacity or
>>> > reserve. AFAIK, none of them access any global variables > aside
>>> > from GC-related stuff (and new is already allowed in pure
>>> > functions). All it would take to make them pure is to mark > the
>>> > declarations for the C functions that they call pure (and > those
>>> > functions aren't part of the public API) and then mark them > as
>>> > pure. Is there any reason why this would be a _bad_ idea?
>>>  pure void f(const(int)[] arr)
>>> {
>>> 	debug /* bypass purity check to pretend assumeSafeAppend is pure
>>> */
>>> 	{
>>> 		assumeSafeAppend(arr);
>>> 	}
>>> 	arr ~= 42;
>>> }
>>>  void main()
>>> {
>>> 	int[] arr = [0, 1, 2, 3, 4];
>>> 	f(arr[1..$-1]);
>>> 	assert(arr[4] == 4, "f has a side effect");
>>> }
>> Except that assumeSafeAppend was misused. It's dangerous to use when  
>> you don't use it properly regardless of purity. By its very nature, it  
>> can screw stuff up.
> When reviewing @safe or pure code, there is inevitably a list of  
> language features that reviewers need to be aware of as bypassing the  
> guarantees that said language features provide, for example  
> assumeUnique, calling @trusted functions, or faux-pure functions which  
> may lead to side effects. It's a question of how big do we want to let  
> this list grow.
> The situation where assumeSafeAppend may be misused due to a bug, but  
> the source of the bug is "hidden out of sight" because it happens inside  
> a pure function, is imaginable. Personally, I never use assumeSafeAppend  
> often enough to justify a potential headache later on.

by the definition of assumeSafeAppend, using it, and then using data in  
the now 'unallocated' space results in undefined behavior.  It should  
definitely not be marked @safe or @trusted, but pure should be ok.

You can also do this in a pure function without issue:

pure void crap(int *data) {*--data = 5;}

Which might or might not be valid, depending on the context.

@safe != pure, and at some point, even compiler guarantees cannot  
guarantee validity.

At the very least, however, reserve and capacity should be pure.


More information about the Digitalmars-d mailing list