www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - inout question

reply Norm <norm.rowtree gmail.com> writes:
Hi,

I'm new to D so can someone explain to me what is happening here?


void func(const char* s, char** e) {
     import core.stdc.stdlib;
     auto result = strtod(s, e);
}

Error: function core.stdc.stdlib.strtod (scope inout(char)* nptr, 
scope inout(char)** endptr) is not callable using argument types 
(const(char*), char**)

I've found I have to use the following:

void func(inout (char)* s, inout(char)** e)


I thought inout was supposed to take const or non-const variants, 
so expected the original const char* s to work.

Thanks,
Norm
Feb 11 2018
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
Norm wrote:

 Hi,

 I'm new to D so can someone explain to me what is happening here?


 void func(const char* s, char** e) {
      import core.stdc.stdlib;
      auto result = strtod(s, e);
 }

 Error: function core.stdc.stdlib.strtod (scope inout(char)* nptr, scope 
 inout(char)** endptr) is not callable using argument types (const(char*), 
 char**)
there is a difference between `const char* s`, and `const(char)* s`. the former means that both `s` and `*s` cannot change, the latter means that `s` can be changed, but `*s` cannot. i.e. the first form means that you cannot do pointer arithmetic with `s`, while with second form you can (only *contents* are const, not the pointer itself). that is, `strtod` wants const *contents*, but not pointer. `const(char)* s`.
Feb 11 2018
parent reply lobo <swamp.lobo gmail.com> writes:
On Monday, 12 February 2018 at 05:37:23 UTC, ketmar wrote:
 Norm wrote:

 Hi,

 I'm new to D so can someone explain to me what is happening 
 here?


 void func(const char* s, char** e) {
      import core.stdc.stdlib;
      auto result = strtod(s, e);
 }

 Error: function core.stdc.stdlib.strtod (scope inout(char)* 
 nptr, scope inout(char)** endptr) is not callable using 
 argument types (const(char*), char**)
there is a difference between `const char* s`, and `const(char)* s`. the former means that both `s` and `*s` cannot change, the latter means that `s` can be changed, but `*s` cannot. i.e. the first form means that you cannot do pointer arithmetic with `s`, while with second form you can (only *contents* are const, not the pointer itself). that is, `strtod` wants const *contents*, but not pointer. `const(char)* s`.
I tried variations of const (char)* s, ... etc. and then stupidly realised the problem was with the second parameter 'e'. inout does behave the way I expected, I was just looking at the wrong parameter. My silly mistake but thanks for your reply. Cheers, Norm
Feb 12 2018
parent ketmar <ketmar ketmar.no-ip.org> writes:
lobo wrote:

sure, i meant that you have to modify the second parameter accordingly. ;-) 
anyway, it's good that you fixed it.
Feb 12 2018
prev sibling next sibling parent Kagamin <spam here.lot> writes:
On Monday, 12 February 2018 at 05:33:16 UTC, Norm wrote:
 I thought inout was supposed to take const or non-const 
 variants, so expected the original const char* s to work.
The problem is in argument e: it's mutable, and strtod stores there a part of s, if s is const you end up with const data available for writing through e. Should be const(char)** e.
Feb 12 2018
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/12/18 12:33 AM, Norm wrote:
 Hi,
 
 I'm new to D so can someone explain to me what is happening here?
 
 
 void func(const char* s, char** e) {
      import core.stdc.stdlib;
      auto result = strtod(s, e);
 }
 
 Error: function core.stdc.stdlib.strtod (scope inout(char)* nptr, scope 
 inout(char)** endptr) is not callable using argument types 
 (const(char*), char**)
 
 I've found I have to use the following:
 
 void func(inout (char)* s, inout(char)** e)
 
 
 I thought inout was supposed to take const or non-const variants, so 
 expected the original const char* s to work.
 
A way to think about inout, when you don't understand why you can't call it, is to think what inout *should* resolve to, and then see if you can assign the existing data to the parameter type. For example, in this case, you are calling: strtod(inout(char)* nptr, inout(char)** endptr) with const char *, and char **. Since const char * and char ** vary on mutability, the compiler is going to try const in place of inout. So try it out: // replace inout with const const(char)* nptr = s; // ok const(char)** endptr = e; // Error I wish the error message was more specific, it would have made things obvious. But due to overloading, it's really hard to create errors that are good explanations, but not too verbose. -Steve
Feb 13 2018