Jump to page: 1 2
Thread overview
How to detect if an array if dynamic or static
Feb 24, 2016
mahdi
Feb 24, 2016
Adam D. Ruppe
Feb 25, 2016
mahdi
Feb 25, 2016
Ali Çehreli
Feb 25, 2016
mahdi
Feb 25, 2016
Kagamin
Feb 25, 2016
sigod
Feb 25, 2016
mahdi
Feb 25, 2016
sigod
Feb 25, 2016
sigod
Feb 25, 2016
Ali Çehreli
Feb 25, 2016
Chris Wright
Feb 25, 2016
Adam D. Ruppe
Feb 25, 2016
Chris Wright
Feb 25, 2016
asdf
Feb 25, 2016
jmh530
February 24, 2016
Suppose we have a function like this:

void diss(int[] array) ...

How can we detect is `array` is static (fixed size) or dynamic, inside the function body?
February 24, 2016
On Wednesday, 24 February 2016 at 21:48:14 UTC, mahdi wrote:
> How can we detect is `array` is static (fixed size) or dynamic, inside the function body?

`array` there is always dynamic because it is not of a fixed size type.

Why do you want to know though?
February 25, 2016
On Wed, 24 Feb 2016 21:48:14 +0000, mahdi wrote:

> Suppose we have a function like this:
> 
> void diss(int[] array) ...
> 
> How can we detect is `array` is static (fixed size) or dynamic,
> inside the function body?

Static arrays point to memory on the stack, inside an aggregate type on the heap, or inside the static data area. In the stack case, you can use this strategy:

extern (C) void* thread_stackBottom();

bool isLocatedOnStack(T)(T[] arr) {
  int i;
  void* top = &i;
  auto bottom = thread_stackBottom();
  return arr.ptr >= min(top, bottom) && arr.ptr <= max(top, bottom);
}

When you get to GC-allocated stuff, there's no way to tell. Static data, I'm not sure.

This probably isn't what you want, though.
February 25, 2016
On Thursday, 25 February 2016 at 01:31:17 UTC, Chris Wright wrote:
> When you get to GC-allocated stuff, there's no way to tell.

The GC is easy, you can simply ask it:

http://dpldocs.info/experimental-docs/core.memory.GC.addrOf.1.html

"If p references memory not originally allocated by this garbage collector, if p is null, or if the garbage collector does not support this operation, null will be returned."


The append operator uses this kind of logic to determine if it is safe to append. The `capacity` property on slices can query, though it is zero in some cases where the GC owns it, but it still needs reallocation to be appended to (e.g. when the array is already at the max length of the allocated block, or when the stomping protection kicks in. See: http://dlang.org/d-array-article.html )
February 25, 2016
On Wednesday, 24 February 2016 at 22:38:04 UTC, Adam D. Ruppe wrote:
> On Wednesday, 24 February 2016 at 21:48:14 UTC, mahdi wrote:
>> How can we detect is `array` is static (fixed size) or dynamic, inside the function body?
>
> `array` there is always dynamic because it is not of a fixed size type.
>
> Why do you want to know though?

I thought we can simply denote `int[] x` in case we have an array argument in D functions. So according to your answer if a function expects a static array, it has to specify size of array in parameter declaration:

void diss(int[3] array) ...  //this expects a static array of size 3
void diss(int[] array) ...  //this expects a dynamic array

is this correct?
February 24, 2016
On 02/24/2016 08:44 PM, mahdi wrote:
> On Wednesday, 24 February 2016 at 22:38:04 UTC, Adam D. Ruppe wrote:
>> On Wednesday, 24 February 2016 at 21:48:14 UTC, mahdi wrote:
>>> How can we detect is `array` is static (fixed size) or dynamic,
>>> inside the function body?
>>
>> `array` there is always dynamic because it is not of a fixed size type.
>>
>> Why do you want to know though?
>
> I thought we can simply denote `int[] x` in case we have an array
> argument in D functions. So according to your answer if a function
> expects a static array, it has to specify size of array in parameter
> declaration:
>
> void diss(int[3] array) ...  //this expects a static array of size 3
> void diss(int[] array) ...  //this expects a dynamic array
>
> is this correct?

Yes.

Note that static arrays are value types. So, if the parameter is int[3], then the argument will be copied. However, you can still take it by reference (with the ref keyword):

import std.stdio;

void diss(ref int[3] array) {
    writeln(typeof(array).stringof);
}

void diss(int[] array) {
    writeln(typeof(array).stringof);
}

void main() {
    int[3] arr;
    diss(arr);
}

Prints:

int[3]

And a reminder that rvalues cannot be bound to ref in D. So, 'ref int[3]' may not be usable in your case.

Ali

February 25, 2016
Thanks.

So when we define the function, we MUST specify the array size to be able to accept a static array?
Can't we just define a function which can accept any static array with any size? (e.g. a function to calculate average of a static int array of any size)?
February 25, 2016
void diss(int n)(ref int[n] array) { }

But to consume array of any size, just take dynamic array as parameter.
February 25, 2016
On Thursday, 25 February 2016 at 10:03:08 UTC, mahdi wrote:
> Thanks.
>
> So when we define the function, we MUST specify the array size to be able to accept a static array?
> Can't we just define a function which can accept any static array with any size? (e.g. a function to calculate average of a static int array of any size)?

Static array can be accepted in place of dynamic:

	void foo()
	{
		int[3] arr = [1, 2, 3];
		
		bar(arr);
	}
	
	void bar(scope int[] arr)
	{
		import std.stdio : writeln;
		writeln(arr); // [1, 2, 3]
	}

But be careful not to escape such variables. Demonstration: http://dpaste.dzfl.pl/613e04d4fe3f
February 25, 2016
On Thursday, 25 February 2016 at 11:50:02 UTC, sigod wrote:
> On Thursday, 25 February 2016 at 10:03:08 UTC, mahdi wrote:
>> Thanks.
>>
>> So when we define the function, we MUST specify the array size to be able to accept a static array?
>> Can't we just define a function which can accept any static array with any size? (e.g. a function to calculate average of a static int array of any size)?
>
> Static array can be accepted in place of dynamic:
>
> 	void foo()
> 	{
> 		int[3] arr = [1, 2, 3];
> 		
> 		bar(arr);
> 	}
> 	
> 	void bar(scope int[] arr)
> 	{
> 		import std.stdio : writeln;
> 		writeln(arr); // [1, 2, 3]
> 	}
>
> But be careful not to escape such variables. Demonstration: http://dpaste.dzfl.pl/613e04d4fe3f

My question: If in your `bar` function, the code tries to add a new element to the dynamic array, it will be completely ok because array is dynamic. BUT if we pass a static array to this function, can this error be detected at compile time (and prevent a runtime error)? If so, how?

« First   ‹ Prev
1 2