Thread overview
Immutable cannot be casted to const when using pointers
Apr 08, 2014
Jeroen Bollen
Apr 08, 2014
John Colvin
Apr 08, 2014
Jeroen Bollen
Filed as Bug
Apr 08, 2014
Jeroen Bollen
Apr 08, 2014
Peter Alexander
Apr 08, 2014
Ali Çehreli
Apr 08, 2014
Artur Skawina
Apr 09, 2014
Jeroen Bollen
April 08, 2014
For some reason this code doesn't work...

module app;

void main() {
	immutable char var = 'a';
	immutable(char)* varPtr = &var;
	test(&varPtr);
}

void test(immutable(char)** param) {
	test2(param);
}

void test2(const(char)** test2) {
	
}

It'll give you " Error: function app.test2 (const(char)** test2) is not callable using argument types (immutable(char)**)", which makes no sense as if a function requests a constant variable, immutable should suffice.

What's even weirder (although it is what should happen), if you remove one of the pointers, it compiles fine.

module app;

void main() {
	immutable char var = 'a';
	test(&var);
}

void test(immutable(char)* param) {
	test2(param);
}

void test2(const(char)* test2) {
	
}

Is this a bug? I'm using DMD.
April 08, 2014
On Tuesday, 8 April 2014 at 21:05:10 UTC, Jeroen Bollen wrote:
> For some reason this code doesn't work...
>
> module app;
>
> void main() {
> 	immutable char var = 'a';
> 	immutable(char)* varPtr = &var;
> 	test(&varPtr);
> }
>
> void test(immutable(char)** param) {
> 	test2(param);
> }
>
> void test2(const(char)** test2) {
> 	
> }
>
> It'll give you " Error: function app.test2 (const(char)** test2) is not callable using argument types (immutable(char)**)", which makes no sense as if a function requests a constant variable, immutable should suffice.
>
> What's even weirder (although it is what should happen), if you remove one of the pointers, it compiles fine.
>
> module app;
>
> void main() {
> 	immutable char var = 'a';
> 	test(&var);
> }
>
> void test(immutable(char)* param) {
> 	test2(param);
> }
>
> void test2(const(char)* test2) {
> 	
> }
>
> Is this a bug? I'm using DMD.

Looks like a bug to me.
April 08, 2014
On Tuesday, 8 April 2014 at 21:07:29 UTC, John Colvin wrote:
> On Tuesday, 8 April 2014 at 21:05:10 UTC, Jeroen Bollen wrote:
>> For some reason this code doesn't work...
>>
>> module app;
>>
>> void main() {
>> 	immutable char var = 'a';
>> 	immutable(char)* varPtr = &var;
>> 	test(&varPtr);
>> }
>>
>> void test(immutable(char)** param) {
>> 	test2(param);
>> }
>>
>> void test2(const(char)** test2) {
>> 	
>> }
>>
>> It'll give you " Error: function app.test2 (const(char)** test2) is not callable using argument types (immutable(char)**)", which makes no sense as if a function requests a constant variable, immutable should suffice.
>>
>> What's even weirder (although it is what should happen), if you remove one of the pointers, it compiles fine.
>>
>> module app;
>>
>> void main() {
>> 	immutable char var = 'a';
>> 	test(&var);
>> }
>>
>> void test(immutable(char)* param) {
>> 	test2(param);
>> }
>>
>> void test2(const(char)* test2) {
>> 	
>> }
>>
>> Is this a bug? I'm using DMD.
>
> Looks like a bug to me.
Alright, filing it.
April 08, 2014
Here we go: https://d.puremagic.com/issues/show_bug.cgi?id=12549
April 08, 2014
On 04/08/14 23:05, Jeroen Bollen wrote:
> For some reason this code doesn't work...
> 
> module app;
> 
> void main() {
>     immutable char var = 'a';
>     immutable(char)* varPtr = &var;
>     test(&varPtr);
> }
> 
> void test(immutable(char)** param) {
>     test2(param);
> }
> 
> void test2(const(char)** test2) {
> 
> }
> 
> It'll give you " Error: function app.test2 (const(char)** test2) is not callable using argument types (immutable(char)**)", which makes no sense as if a function requests a constant variable, immutable should suffice.

   void test2(const(char)** test2) {
      static char b = 'b';
      *test2 = &b;
   }

artur
April 08, 2014
On Tuesday, 8 April 2014 at 21:13:47 UTC, Jeroen Bollen wrote:
> Here we go: https://d.puremagic.com/issues/show_bug.cgi?id=12549

Not a bug:

What you are asking for is to allow immutable(T)** and int** to convert to const(T)**

int a = 0;
int* pa = &a;
const(int)** ppa = &pa; // not currently allowed

immutable(int) b = 1;

*ppa = &b; // equivalent to pa = &b!!! i.e. pa (mutable) now points at b (immutable)!!!





April 08, 2014
On 04/08/2014 02:38 PM, Peter Alexander wrote:
> On Tuesday, 8 April 2014 at 21:13:47 UTC, Jeroen Bollen wrote:
>> Here we go: https://d.puremagic.com/issues/show_bug.cgi?id=12549
>
> Not a bug:

Yeah. A known issue in C and C++ as well:

  http://www.parashift.com/c++-faq/constptrptr-conversion.html

Ali

April 08, 2014
On Tue, 08 Apr 2014 17:05:09 -0400, Jeroen Bollen <jbinero@gmail.com> wrote:

> For some reason this code doesn't work...
>
> module app;
>
> void main() {
> 	immutable char var = 'a';
> 	immutable(char)* varPtr = &var;
> 	test(&varPtr);
> }
>
> void test(immutable(char)** param) {
> 	test2(param);
> }
>
> void test2(const(char)** test2) {
> 	
> }
>

...

> Is this a bug? I'm using DMD.

No, it's intended. If that was allowed, you could inadvertently overwrite immutable data without a cast.

The rule of thumb is, 2 or more references deep does not implicitly convert. One reference deep is OK.

-Steve
April 09, 2014
On Tuesday, 8 April 2014 at 21:53:58 UTC, Steven Schveighoffer wrote:
> The rule of thumb is, 2 or more references deep does not implicitly convert. One reference deep is OK.
>
> -Steve

For some reason I was expecting that to rhyme. :P

Anyways thanks all, makes sense now. Are there any workarounds? The function taking the const int** is external(C) so I'm not sure what to do.
April 10, 2014
On Wed, 09 Apr 2014 06:25:34 -0400, Jeroen Bollen <jbinero@gmail.com> wrote:

> On Tuesday, 8 April 2014 at 21:53:58 UTC, Steven Schveighoffer wrote:
>> The rule of thumb is, 2 or more references deep does not implicitly convert. One reference deep is OK.
>>
>> -Steve
>
> For some reason I was expecting that to rhyme. :P
>
> Anyways thanks all, makes sense now. Are there any workarounds? The function taking the const int** is external(C) so I'm not sure what to do.

Without knowing more information, it's hard to say.

You can create a temporary:
// immutable(char)** v
const(char)* x = *v;
foo(&x);

-Steve