Jump to page: 1 2
Thread overview
Is this a bug?
Apr 28, 2014
Andrey
Apr 28, 2014
John Colvin
Apr 28, 2014
Andrey
Apr 28, 2014
John Colvin
Apr 28, 2014
Andrey
Apr 28, 2014
bearophile
Apr 28, 2014
John Colvin
Apr 29, 2014
Andrey
Apr 29, 2014
Andrey
Apr 29, 2014
Marc Schütz
Apr 29, 2014
John Colvin
Apr 29, 2014
Ali Çehreli
Apr 29, 2014
Meta
Apr 29, 2014
Ali Çehreli
Apr 30, 2014
David Held
Apr 28, 2014
bearophile
April 28, 2014
Could anyone please explain to me, why do I have error message on this piece of code?

alias short Type1;
alias Type1[100]* Type2; // pointer to an array
struct Type3
{
	Type2 f
}
void foo()
{
   Type3* b;
   Type1  d;
   d = b.f[10]; // compilation error: cannot implicitly convert expression ((*b).f[10]) of type short[100] to short
   d = b.f[0][10]; // ok
}

Thank you in advance
April 28, 2014
On Monday, 28 April 2014 at 08:58:41 UTC, Andrey wrote:
> Could anyone please explain to me, why do I have error message on this piece of code?
>
> alias short Type1;
> alias Type1[100]* Type2; // pointer to an array
> struct Type3
> {
> 	Type2 f
> }
> void foo()
> {
>    Type3* b;
>    Type1  d;
>    d = b.f[10]; // compilation error: cannot implicitly convert expression ((*b).f[10]) of type short[100] to short
>    d = b.f[0][10]; // ok
> }
>
> Thank you in advance

not a bug.

b.f[10] is indexing the pointer to the array, not the array itself.

b.f[0][10] is indexing the array (with the 10), but I would argue it is better to write *(b.f)[10] so as to be clear that f is not an array.

What is the reason you are using a pointer to a struct containing a pointer to a static array? It's often not necessary to work like that.
April 28, 2014
> not a bug.
>
> b.f[10] is indexing the pointer to the array, not the array itself.
>
> b.f[0][10] is indexing the array (with the 10), but I would argue it is better to write *(b.f)[10] so as to be clear that f is not an array.

thank you, John.

compiler said that '*(b.f)[10]' is deprecated, and I should write like this

void foo()
{
   Type3 b;
   Type1  d;
   d = *(b.f[10]).ptr;
}

which looks completely weird for me...

> What is the reason you are using a pointer to a struct containing a pointer to a static array? It's often not necessary to work like that.

it is just a sample... in real code the struct contains a lot of fields
April 28, 2014
Andrey:

> Could anyone please explain to me, why do I have error message on this piece of code?

In this thread you are doing some mistakes. This code seems OK:

alias TData = short;
alias TArray = TData[100];

struct MyStruct {
    TArray* arrPtr;
}

void main() {
    MyStruct* t3 = new MyStruct(new TArray[1].ptr);
    TData data0 = (*t3.arrPtr)[99];
}


D is working as designed. (The only small problem is that you can't "new" a fixed size array, so I have had to allocate a dynamic array of TArray of length 1 and take the pointer to its first item. Another alternative solution is to wrap TArray into a struct.)

Such kind of code is possible in D, but it should be quite uncommon in library code (and it can't be marked safe). There are usually simpler ways to do similar things in D. So perhaps there are ways to simplify your data structure (here I have kept the same structure you have used in the example).

Bye,
bearophile
April 28, 2014
On Monday, 28 April 2014 at 09:36:08 UTC, Andrey wrote:
>> not a bug.
>>
>> b.f[10] is indexing the pointer to the array, not the array itself.
>>
>> b.f[0][10] is indexing the array (with the 10), but I would argue it is better to write *(b.f)[10] so as to be clear that f is not an array.
>
> thank you, John.
>
> compiler said that '*(b.f)[10]' is deprecated, and I should write like this
>
> void foo()
> {
>    Type3 b;
>    Type1  d;
>    d = *(b.f[10]).ptr;
> }

struct T
{
	int[10]* f;
}

void main()
{
	int[10] test;
	T t = T(&test);
	T* b = &t;
	
	auto d = (*(b.f))[4]; //ugly but clear.
	d = b.f[0][4]; //prettier but less clear.
}

note the extra brackets on the ugly one, I forgot them before.
April 28, 2014
bearophile, John, probably, my example was not clear...

The code below works.

alias short Type1;
alias Type1[100]* Type2; // if I take out '*' I will have to type it everywhere, because arrays in D2 always 'by value'

struct Type3
{
	Type1 key;
	int  flags;
        int  arrLen;
	Type2 f; // this struct can be *optionally* extended by the array
}

void foo(Type3* b)
{
   Type1  d;
   d = (*(*b).f)[10];
}

Thank you, I appreciate your help!!
April 28, 2014
Andrey:

> alias short Type1;

The "alias X Y;" syntax is going to be deprecated, so use "alias Y = X;" if your compiler already supports it.


> alias Type1[100]* Type2; // if I take out '*' I will have to type it everywhere, because arrays in D2 always 'by value'

Adding the * everywhere could be a good thing, because it makes the code more explicit. Even in Linux kernel typedefs that just mask out a pointer are not appreciated a lot. D code that uses pointers to fixed size arrays is very uncommon in D, so adding a * there is not going to cause troubles.


> struct Type3
> {
> 	Type1 key;
> 	int  flags;
>         int  arrLen;
> 	Type2 f; // this struct can be *optionally* extended by the array
> }

The common way to create a variable length struct in D is to use a zero length fixed size array (and no pointers):

struct Type3 {
    Type1 key;
    int flags;
    int arrLen;
    Type1[0] f;
}


But if you don't mind the double indirection using a dynamic array is simpler:

struct Type3 {
    Type1 key;
    int flags;
    Type1[] f;
}

Bye,
bearophile
April 28, 2014
On Mon, 28 Apr 2014 06:04:53 -0400, John Colvin <john.loughran.colvin@gmail.com> wrote:

> On Monday, 28 April 2014 at 09:36:08 UTC, Andrey wrote:
>>> not a bug.
>>>
>>> b.f[10] is indexing the pointer to the array, not the array itself.
>>>
>>> b.f[0][10] is indexing the array (with the 10), but I would argue it is better to write *(b.f)[10] so as to be clear that f is not an array.
>>
>> thank you, John.
>>
>> compiler said that '*(b.f)[10]' is deprecated, and I should write like this
>>
>> void foo()
>> {
>>    Type3 b;
>>    Type1  d;
>>    d = *(b.f[10]).ptr;
>> }
>
> struct T
> {
> 	int[10]* f;
> }
>
> void main()
> {
> 	int[10] test;
> 	T t = T(&test);
> 	T* b = &t;
> 	
> 	auto d = (*(b.f))[4]; //ugly but clear.
> 	d = b.f[0][4]; //prettier but less clear.
> }
>
> note the extra brackets on the ugly one, I forgot them before.

You don't need them. (*b.f)[4] works. '.' has precedence over '*'.

-Steve
April 28, 2014
On Monday, 28 April 2014 at 14:02:33 UTC, Steven Schveighoffer wrote:
> On Mon, 28 Apr 2014 06:04:53 -0400, John Colvin <john.loughran.colvin@gmail.com> wrote:
>
>> On Monday, 28 April 2014 at 09:36:08 UTC, Andrey wrote:
>>>> not a bug.
>>>>
>>>> b.f[10] is indexing the pointer to the array, not the array itself.
>>>>
>>>> b.f[0][10] is indexing the array (with the 10), but I would argue it is better to write *(b.f)[10] so as to be clear that f is not an array.
>>>
>>> thank you, John.
>>>
>>> compiler said that '*(b.f)[10]' is deprecated, and I should write like this
>>>
>>> void foo()
>>> {
>>>   Type3 b;
>>>   Type1  d;
>>>   d = *(b.f[10]).ptr;
>>> }
>>
>> struct T
>> {
>> 	int[10]* f;
>> }
>>
>> void main()
>> {
>> 	int[10] test;
>> 	T t = T(&test);
>> 	T* b = &t;
>> 	
>> 	auto d = (*(b.f))[4]; //ugly but clear.
>> 	d = b.f[0][4]; //prettier but less clear.
>> }
>>
>> note the extra brackets on the ugly one, I forgot them before.
>
> You don't need them. (*b.f)[4] works. '.' has precedence over '*'.
>
> -Steve

The extra ones I referred to were the outer ones. Nonetheless, you're example is correct.
April 29, 2014
Ok, thanks a lot..

About dynamic arrays: I haven't found any information about internal representation of the D structures. E.g. do dynamic arrays have reference counter?

Nevermind, I'm gonna use Type2[0] syntax.
« First   ‹ Prev
1 2