May 25, 2004
imr1984 wrote:
> inout for a readonly parameter is inaccurate and misleading. 
> 
> Or - here is an idea - Since no one actually uses the 'in' keyword, why not make
> the in keyword explicitly mean pass by reference, and the function is not
> allowed to write to the pointer. This would be perfect.

haha. That's what I thought 'in' did before I figured out it didn't really mean anything.

It makes sense though. 'out' means out only. 'inout' means both. 'in' would make sense to mean in only.
May 25, 2004
> Maybe extern(C/Windows/Pascal/...) should not use the in/inout/out modifiers
> at all but offer a completely separate set of modifiers fit for each case?

While you are at it. Allow the the extern(C/Windows/Pascal) functions have 'const' in the prototype. I end up having to do this a lot:

extern(C)
{
void lookyLooky(/*const*/ Something* something);
}

In one of the C libraries I use I could just grab all of the functions intact without any changes if I didn't have to comment out all the 'const'.

May 25, 2004
Norbert Nemec wrote:
> Andy Friesen wrote:
>>Why is it faster?  And how small is small?
> 
> Good question. If the struct is no bigger than one pointer, it is clear that
> it is faster since you simply save one step of dereferencing. If it is
> slightly bigger, dereferencing may still be more expensive than copying.
> Hard to tll.

A function using such a struct would be able to create a private copy if it was determined that doing so would be faster, right?

> Maybe extern(C/Windows/Pascal/...) should not use the in/inout/out modifiers
> at all but offer a completely separate set of modifiers fit for each case?

Everything except 'in' should be illegal, I think.  Those conventions are already well established standards; D shouldn't mess with them.

 -- andy
May 25, 2004
On Tue, 25 May 2004 08:44:21 +0200, Norbert Nemec <Norbert.Nemec@gmx.de> wrote:
> Then this boils down to the good old war about "const". Walter decided to
> make "const" a storage class, not a type modifier.

I think this was a good decision. An object *is* either const or not. But lets not re-start this argument.

> This means, we have
> const objects, you can take a pointer from them, but then the compiler does
> not help you in tracking that they were const.

This should be fixed. Can you point a 'pointer to non-const' (does D even have 'pointer to const') at a const object? if so, perhaps this shouldn't be allowed.

> Introducing "ref" in addition to "inout" would just hide this fact in a very
> obscure way. "inout mytype arg" would be "mytype &arg" in C++, while "ref
> mytype arg" would be "const mytype &arg".

I don't like the 'ref' idea, I think in, out and inout can do what we need.

> I believe that whole business of "in", "out" and "inout" arguments is
> flawed. My first expectation, when I saw these was, that that they are
> "copy-in/copy-out" arguments. The specs are not very precise when they talk
> about this question. Somehow, I have the feeling, that D tries to hide the
> complexity of reference/value arguments from the user, but, at the same
> time, obscures and cripples the concept completely.
>
> My opinion: neither the C++ nor the D way are the solution. I don't know the
> solution, but it has to be out there somewhere.

If we adopt this idea of passing by reference *all* the time, you'd have something like:

in  - pass by reference, any attempt to modify causes a compile time error.
out - pass by reference, initialized on entry.
inout - pass by reference.

a const object passed as an inout or out parameter would cause a compile time error.

(I realise it may not be simple to detect the above compile time errors)

I don't think you need to copy-in/copy-out. If the function writer wants to modify an 'in' parameter, then it's either not an 'in' parameter, or they only want to do it for the duration of the function so...

int fn(in int _a) {
  int a = _a;
}

will suffice to make a copy they can modify for the duration of the function.

What am I missing?

Regan.

> Kris wrote:
>
>> One cannot use 'inout' with a const struct, since by definition it's
>> read-only.
>>
>> - Kris
>>
>> "Carlos Santander B." <carlos8294@msn.com> wrote in message
>> news:c8udnv$205u$1@digitaldaemon.com...
>>> "imr1984" <imr1984_member@pathlink.com> escribió en el mensaje
>>> news:c8tbvq$fm$1@digitaldaemon.com
>>> | I think D needs a 'ref' keyword like C# has. This way large structs can
>> be
>>> | passed by reference without nasty pointers. The way i see it, this is
>> the
>>> only
>>> | way to support this because as Stewart says if you have a function
>>> exported from
>>> | a library, and it takes a struct, the only way for the compiler to know
>>> that the
>>> | exported func takes the struct by Ref is if its indicated in the
>> prototype
>>> with
>>> | the ref keyword.
>>> |
>>>
>>> What's wrong with inout?
>>>
>>> -----------------------
>>> Carlos Santander Bernal
>>>
>>>
>

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
May 25, 2004
On Tue, 25 May 2004 08:14:17 -0700, Andy Friesen wrote:

[snip]
> 
> What might be better is if the ABI said that all structs are always passed by reference.  In the case of 'in' parameters, the compiler would be responsible for creating a temporary copy if one is needed. (ie if it thinks the struct is written to)
> 
> Are there any arguments for passing structs by value?
> 

There are a couple of Windows API calls that pass a POINT struct by value.

-- 
Derek
26/May/04 9:40:42 AM
May 26, 2004
Derek Parnell wrote:
> On Tue, 25 May 2004 08:14:17 -0700, Andy Friesen wrote:
> 
> [snip]
> 
>>What might be better is if the ABI said that all structs are always passed by reference.  In the case of 'in' parameters, the compiler would be responsible for creating a temporary copy if one is needed. (ie if it thinks the struct is written to)
>>
>>Are there any arguments for passing structs by value?
>>
> 
> 
> There are a couple of Windows API calls that pass a POINT struct by value.

Okay.  That more or less solidifies the case for extern C, Pascal, and Windows all behaving exactly as they do now.

Should extern (D) preserve this behaviour for consistency's sake, or is this an opportunity for D to do the Right Thing even in the face of naive code?  (indeed, make the naive approach the best one)

 -- andy
May 26, 2004
Andy Friesen wrote:

> imr1984 wrote:
> 
>> inout for a readonly parameter is inaccurate and misleading.
>> 
>> Or - here is an idea - Since no one actually uses the 'in' keyword, why not make the in keyword explicitly mean pass by reference, and the function is not allowed to write to the pointer. This would be perfect.
> 
> You would need to make sure that 'in' references are only passed to methods as 'in' arguments, and so on and so forth.

True, but every function argument would be readonly by default! Either it has no argument modifier, meaning call-by-value, or it is 'in', meaning call by read-only-reference.

> It's C++ const all over again.

No! The problem in C++ was, that "const" had to be explicitly specified. So if you forgot to say it in some function, you had problems using that function legitimately. In D, you will have to explicitly state 'inout', if you want to have a read-write reference.

> What might be better is if the ABI said that all structs are always passed by reference.  In the case of 'in' parameters, the compiler would be responsible for creating a temporary copy if one is needed. (ie if it thinks the struct is written to)

Why not prohibit writing to function arguments alltogether (unless they are
inout/out)?

It is that strange C feature to make every argument automatically a local variable. I always found it bad style to use this. If you need a local variable, why not just declare one?

May 26, 2004
Norbert Nemec wrote:

> The problem in C++ was, that "const" had to be explicitly specified. So
> if you forgot to say it in some function, you had problems using that
> function legitimately. In D, you will have to explicitly state 'inout', if
> you want to have a read-write reference.

C++ const means const methods, const references, and all the headaches that they entail.  The theory seems sound enough, but the compiler can't use const to optimize anything and I can't recall any instances offhand where const saved the day.  I can, however, recall a whole lot of compiler errors caused by forgetting to const this or that.

>>What might be better is if the ABI said that all structs are always
>>passed by reference.  In the case of 'in' parameters, the compiler would
>>be responsible for creating a temporary copy if one is needed. (ie if it
>>thinks the struct is written to)
> 
> Why not prohibit writing to function arguments alltogether (unless they are
> inout/out)?
> 
> It is that strange C feature to make every argument automatically a local
> variable. I always found it bad style to use this. If you need a local
> variable, why not just declare one?

Most languages I have used allow this.  Why not?

 -- andy
May 26, 2004
Andy Friesen wrote:

> Norbert Nemec wrote:
> 
>> The problem in C++ was, that "const" had to be explicitly specified. So if you forgot to say it in some function, you had problems using that function legitimately. In D, you will have to explicitly state 'inout', if you want to have a read-write reference.
> 
> C++ const means const methods, const references, and all the headaches that they entail.  The theory seems sound enough, but the compiler can't use const to optimize anything and I can't recall any instances offhand where const saved the day.  I can, however, recall a whole lot of compiler errors caused by forgetting to const this or that.

The problem in C++ is that you can have references/pointers to const. If you disallow taking the address of a const variable, the problem of const references disappears. Objects can never be const, since they are always handled as reference and you cannot have literal objects. This solves the demand for const methods.

Leaves us only with const for call-by-reference arguments: this could be solved by making arguments read-only generally. If "in" would declare an argument as call-by-reference argument, this would mean you can only use it in places where a const would be allowed as well. If you use a literal as "in" argument, the compiler will have to place it in the constant data segment to be able to create a reference to it, but there is no chance anyone might ever try to write to that memory.

>> Why not prohibit writing to function arguments alltogether (unless they
>> are inout/out)?
>> 
>> It is that strange C feature to make every argument automatically a local variable. I always found it bad style to use this. If you need a local variable, why not just declare one?
> 
> Most languages I have used allow this.  Why not?

Because it collides with call-by-reference. For "inout/out", there is no problem, since assigning to the referenced data actually means changing that data outside of the function. For "in" parameters, on the other hand, the compiler will have to make a copy of that data, which, in a way, defies the purpose of call-by-reference.

Most old programming languages allow it, since it may save one copy-operation. Today, with optimizing compilers, this does not really matter any more, so I can only call it bad programming style.
May 26, 2004
In article <c91jku$11uv$1@digitaldaemon.com>, Andy Friesen says...
>
>C++ const means const methods, const references, and all the headaches that they entail.  The theory seems sound enough, but the compiler can't use const to optimize anything and I can't recall any instances offhand where const saved the day.

Ooh, I can think of squillions of such examples. And at least one example when one of my time "worked around" my const declaration with a pointer trick, and held the project up for about two weeks while the whole team attempted to figure out how and why the heap was getting corrupted! Our app was multithreaded - that's when these things really matter.

>I can, however, recall a whole lot of compiler errors caused by forgetting to const this or that.

That's what happens when you call functions written by other people who DIDN'T use const.

I've always thought that C++ would be a much better language if it everything was const by default, and you needed a keyword, nonconst, say, to specify otherwise. That way, if you wrote a function like:

>       char * strcpy(char * dst, char * src);

it would fail to compile until you changed it to:

>       char * strcpy(nonconst char * dst, char * src);

(although the error would refer to the line that attempted to modify *dst, not the declaration). As things stand, forgetting const is not a compile error. Instead, it becomes impossible to use const unless you go the whole hog and change every single function you call to use the C++ const convention.

In the case of D, I would dearly love to be able to declare a function like:

>       void myFunction( in MyObject myObject )

****and have the compiler flag an error**** if the referenced object is modified. I cannot stress how greatly this would assist in bug catching.

Right now the only way to do anything even remotely similar to this is:

>       void myFunction( in MyObject myObject )
>       in
>       {
>           myObject_backup = new MyObject(myObject);
>       }
>       out
>       {
>           assert(myObject == myObject_backup);
>       }
>       body
>       {
>           debug MyObject myObject_backup;
>       }

Sheesh!

After all, putting const (or in, or nonconst, or whatever) into a function declaration is simply that - a contract which the function must fulfil. If it fails to fulfil that contract, it's a bug.

With all of D's emphasis on contracts, it baffles me why D doesn't implement this most useful one.

Arcane Jill