Thread overview
is pointer
Mar 19, 2010
bearophile
Mar 20, 2010
Moritz Warning
Mar 20, 2010
Ellery Newcomer
Mar 20, 2010
bearophile
Mar 20, 2010
Daniel Keep
Mar 20, 2010
bearophile
Mar 20, 2010
Jacob Carlborg
March 19, 2010
(I am looking for rough corners in D, or in my knowledge of D.)

In this page: http://www.digitalmars.com/d/2.0/templates-revisited.html

In the section "Template Parameters" there is written:

P:P*,         // P must be a pointer type

-----------------

So I have written this D2 program:


template IsPointer1(T) {
    enum bool IsPointer1 = is(T : T*);
}
void main() {
    int* ptr;
    static assert(IsPointer1!(typeof(ptr))); // Err
}


But it asserts, do you know why?

-----------------

Then I have written a different program:


template IsPointer2(T) {
    enum bool IsPointer2 = is(typeof(*T)) || is(T == void*);
}
void main() {
    int* ptr;
    static assert(IsPointer2!(typeof(ptr))); // OK
    int[] arr;
    static assert(!IsPointer2!(typeof(arr))); // Err
}


Do you know why IsPointer2 is true for the dynamic array type too?

(I know in std.traits of Phobos 2 there is an isPointer).

Thank you,
bye,
bearophile
March 20, 2010
On Fri, 19 Mar 2010 19:29:24 -0400, bearophile wrote:

> (I am looking for rough corners in D, or in my knowledge of D.)
[..]
> 
> template IsPointer1(T) {
>     enum bool IsPointer1 = is(T : T*);
> }
> void main() {
>     int* ptr;
>     static assert(IsPointer1!(typeof(ptr))); // Err
> }
> 
> 
> But it asserts, do you know why?

I think the problem is that is(T : T*) becomes is(int* : int**)
and that's false.



> Then I have written a different program:
[..]
>     enum bool IsPointer2 = is(typeof(*T)) || is(T == void*);
[..]
> 
> 
> Do you know why IsPointer2 is true for the dynamic array type too?
.. no idea.
March 20, 2010
On 03/19/2010 07:53 PM, Moritz Warning wrote:
> On Fri, 19 Mar 2010 19:29:24 -0400, bearophile wrote:
>
>> (I am looking for rough corners in D, or in my knowledge of D.)
> [..]
>>
>> template IsPointer1(T) {
>>      enum bool IsPointer1 = is(T : T*);
>> }
>> void main() {
>>      int* ptr;
>>      static assert(IsPointer1!(typeof(ptr))); // Err
>> }
>>
>>
>> But it asserts, do you know why?
>
> I think the problem is that is(T : T*) becomes is(int* : int**)
> and that's false.
>
>
>
>> Then I have written a different program:
> [..]
>>      enum bool IsPointer2 = is(typeof(*T)) || is(T == void*);
> [..]
>>
>>
>> Do you know why IsPointer2 is true for the dynamic array type too?
> .. no idea.

Curious behavior DArrays exhibit:

void main(){
  int[] i = [5,4,3,2,1];
  writeln(*i); // prints 5
}

Ick.
March 20, 2010
Moritz Warning:
>I think the problem is that is(T : T*) becomes is(int* : int**) and that's false.<

Thank you, you can be right.
So D docs are wrong, or that syntax has a semantic bug, or I have not understood the situation yet.
If someone else has ideas I'm all ears.

-------------

Ellery Newcomer:
> Curious behavior DArrays exhibit:

Thankfully this doesn't compile:

import std.stdio: writeln;
import std.c.stdlib: calloc;

struct Array {
    int* ptr;
    size_t length;
}

void main() {
    enum size_t N = 5;
    int* p = cast(int*)calloc(N, int.sizeof);
    Array a = Array(p, N);
    writeln(*a);
}

This solves the second question, I'll file it as a bug or specs bug. Thank you.

Bye,
bearophile
March 20, 2010
bearophile wrote:
> (I am looking for rough corners in D, or in my knowledge of D.)
> 
> In this page: http://www.digitalmars.com/d/2.0/templates-revisited.html
> 
> In the section "Template Parameters" there is written:
> 
> P:P*,         // P must be a pointer type
> 
> -----------------
> 
> So I have written this D2 program:
> 
> 
> template IsPointer1(T) {
>     enum bool IsPointer1 = is(T : T*);
> }
> void main() {
>     int* ptr;
>     static assert(IsPointer1!(typeof(ptr))); // Err
> }
> 
> 
> But it asserts, do you know why?

You do realise that "Template Parameters" are a completely different thing to "is expressions", right?
March 20, 2010
Daniel Keep:
> You do realise that "Template Parameters" are a completely different thing to "is expressions", right?

Nope. And from the other answers by Moritz and Ellery it seems I am not alone :-) You are right, this works:


template IsPointer1(T:T*) {
    enum bool IsPointer1 = true;
}
template IsPointer1(T) {
    enum bool IsPointer1 = false;
}
void main() {
    static assert(IsPointer1!(int*));
    static assert(!IsPointer1!(int));
    static assert(!IsPointer1!(int[]));
}


This syntax looks too much similar to the syntax with is():
template IsPointer1(T:T*) {
It's a syntax collision. You realize that I will not be the only one to fall in this little trap.

Bye and thank you,
bearophile
March 20, 2010
On 2010-03-20 00.29, bearophile wrote:
> (I am looking for rough corners in D, or in my knowledge of D.)
>
> In this page:
> http://www.digitalmars.com/d/2.0/templates-revisited.html
>
> In the section "Template Parameters" there is written:
>
> P:P*,         // P must be a pointer type
>
> -----------------
>
> So I have written this D2 program:
>
>
> template IsPointer1(T) {
>      enum bool IsPointer1 = is(T : T*);
> }
> void main() {
>      int* ptr;
>      static assert(IsPointer1!(typeof(ptr))); // Err
> }
>
>
> But it asserts, do you know why?

You can do like this:

template IsPointer (T)
{
	enum IsPointer = false;
}

template IsPointer (T : T*)
{
	enum IsPointer = true;
}

> -----------------
>
> Then I have written a different program:
>
>
> template IsPointer2(T) {
>      enum bool IsPointer2 = is(typeof(*T)) || is(T == void*);
> }
> void main() {
>      int* ptr;
>      static assert(IsPointer2!(typeof(ptr))); // OK
>      int[] arr;
>      static assert(!IsPointer2!(typeof(arr))); // Err
> }
>
>
> Do you know why IsPointer2 is true for the dynamic array type too?
>
> (I know in std.traits of Phobos 2 there is an isPointer).
>
> Thank you,
> bye,
> bearophile