October 24, 2002 Re: Was (Re: "inout" is wrong name) now ... immutability | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Wynn | "Mike Wynn" <mike.wynn@l8night.co.uk> wrote in message news:ap0uki$119j$1@digitaldaemon.com... > as an aside, have you though about changing the build from a 2 stage > compile, link into a 3 stage build > so it is compile,gather,link, where the gather stage, pulls in all the > objects, and then with a full view of the final codebase can convert some > calls to non-virtual and perform optimisations on immutable items etc, in a > similar fashion to Java/CLR dynamic compilers. Too many void*'s in C++ usually put an end to these kinds of global optimizations. I tried to do something similar once with function register usage across separate compilation items, it just worked out that so many things defeat the optimization that there wasn't a payoff. |
October 25, 2002 Re: Was (Re: "inout" is wrong name) now ... immutability | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Isn't this a good opportunity to fix the language so that it supports these kinds of optimizations, rather than hinder them? Surely something can be done. What things would you need to be true in order to cache locals in registers across function calls? Make an attribute that supports the functionality, and make the compiler enforce it. You don't have to use it, but if you do, you know the compiler will be able to generate better code. Maybe "const" isn't the right choice of words, maybe "cachelocalaccess" would be better. I still think that readonly is a desirable attribute even if it doesn't buy you any optimization potential. It seems like if you don't have it, you leave dangerous holes in a component's armor that can be abused without so much as a typecast or compiler warning. Or abused completely by accident. Sean "Walter" <walter@digitalmars.com> wrote in message news:ap9jaq$l0m$1@digitaldaemon.com... > > "Sean L. Palmer" <seanpalmer@directvinternet.com> wrote in message news:ap0mop$oka$1@digitaldaemon.com... > > If you have this situation you should use volatile on things you want changes to show up immediately on. Then the change will take effect on > all > > copies immediately, but everything else can use the old values. > > If you think something might change, don't keep a const reference to it. > > Just because something might break isn't a good enough reason not to do > the > > optimization. Just needs enough language warnings and good support for > > volatile too. > > In many cases you use const when you don't expect something to change > and/or > > don't care if it changes. > > Unfortunately, I can't implement compiler optimizations that assume const means const, because it doesn't and too many programs break. This is one of > the reasons why const is useless as a type modifier. > > |
October 29, 2002 Re: Was (Re: "inout" is wrong name) now ... immutability | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <seanpalmer@directvinternet.com> wrote in message news:apad69$1hgm$1@digitaldaemon.com... > Isn't this a good opportunity to fix the language so that it supports these > kinds of optimizations, rather than hinder them? > > Surely something can be done. > > What things would you need to be true in order to cache locals in registers > across function calls? Make an attribute that supports the functionality, and make the compiler enforce it. You don't have to use it, but if you do, > you know the compiler will be able to generate better code. Maybe "const" isn't the right choice of words, maybe "cachelocalaccess" would be better. > > I still think that readonly is a desirable attribute even if it doesn't buy > you any optimization potential. It seems like if you don't have it, you leave dangerous holes in a component's armor that can be abused without so much as a typecast or compiler warning. Or abused completely by accident. Perhaps in a future version, but for now I think things are pretty full. Gotta do foreach, lambda functions, etc. <g> |
February 12, 2004 Re: "inout" is wrong name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Evan McClanahan | In article <anrqs3$ic5$1@digitaldaemon.com>, Evan McClanahan says... .. >> void fn(inout int a, inout int b) >> { >> a = 3; >> printf("a = %d\n", a); >> printf("b = %d\n", b); >> printf("global_var = %d\n", global_var); >> } >> >> int main() >> { >> global_var = 2; >> fn(global_var, global_var); >> return 0; >> } >> >> A "real" inout parameter passing would print: >> a = 3 >> b = 2 >> global_var = 2 Actually, for pass-by-copy, the value of global_var is ambiguous. The value of either 2 or 3 is possible depending on whether we look at parameters from left-to-right or right-to-left. > >I don't think that I know what you mean. Semantically, inout should be >something that expects a value in, but can still change it in the >function. So I would expect inout to do what I imagine that it does: >a = 3 >b = 3 >global_var = 3 > >> So it is not "inout" but "ref" > >This is something of a pathological case, perhaps even an error, since both inouts end up pointing to the same place. Yeah, inout might be a ref, but I imagine that it would be extremely hard for the compiler to do compile time checking that the inout parameters are all different for each function. In fact, I can't really see a case where it would be proper or useful to do this, nor a way to pass it back in a reasonable manner in any case. I think that the keyword is clear enough, and that if possible what you're doing in the above code should be classed as an error, or at least proscribed in the documentation. > >Evan Let me just recap what the three alternatives are, their strengths and weakness, and then my suggested approach to solving this problem. inout: This indicates that a parameter is used for both input and output. The problem seems to be the calling mechanism used. For instance, are we using pass-by-reference, pass-by-value-result (pass-by-copy), or pass-by-name. ref: This indicates that the parameter is passed-by-reference (a pointer). The problem is that this method does not indicate that the parameter is used for input, output, or both. shared: This particular name really does not tell you anything, other than the fact the variable can be modified by the called routine. This is perhaps the worst option because it leaves two things unanswered: (1) are we using pass-by-reference or pass-by-value-result; and, (2) is the parameter used for input, output, or both. For those that don't know the difference between these calling methods, here is a quick definition of each, assuming the parameter we are passing is called ARG. pass-by-value: The contents ARG are passed to the function. pass-by-reference: The address of ARG is passed to the function, allowing modification by the called function. pass-by-value-result: A temporary, T, is assigned the value of ARG. Next, we call the function using pass-by-reference using T in place of ARG. Lastly, when the function returns ARG is assigned the final value of T. pass-by-name: This one is best explained by an example (in pseudo-C): int index; int array[2] = {2, 2}; void sub(int param /*assuming pass-by-name*/) { param = 3; index++; param = 5; } void main() { index = 0; sub(aray[index]); // array is now {3, 5} } The reason for this is because the body of sub gets transformed into: array[index] = 3; index++; array[index] = 5; Having said all of that, I believe the following rules present a much more elegant solution to all of these problems: 1) All parameters shall be passed via either pass-by-value or pass-by-reference. 2) All parameters deemed as input shall be read-only. 3) The parameter passing mechanism used for input parameters shall be determined by the compiler. 4) All output parameters shall be passed in using pass-by-reference. 5) Output parameters that are referenced prior to writing to them shall result in an error message. 6) All inout parameters shall be passed in pass-by-reference. 7) All inout parameteres shall be initialized prior to the call of said function. (Note, that this would be easy to verifiy for a local variable but can be extremely hard if not impossible for globals). 8) All parameters shall be assumed to be an input parameter unless explicitly stated otherwise. In some of the examples, people want to pass in a large array without doing the copy, and as such labeled them as inout. Note that this is no longer necessary due to rules (2) and (3). Other problems such as those presented in function 'fn' are covered by rules (1) and (6). - Eric |
February 12, 2004 Re: | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | >2) is useless for optimization, since you can still change it In C++, but not neccessarily in D!?! There simply shouldn't be a const_cast<>() and you should restrict const parameters not to alias with other non const parameters. Are there any other problems? I don't know if "mutable" could cause problems, if D would get something like this. >4) in my experience, it has never found a bug for me It has for me. |
February 12, 2004 Re: Was (Re: | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | >Too many void*'s in C++ usually put an end to these kinds of global optimizations. I tried to do something similar once with function register usage across separate compilation items, it just worked out that so many things defeat the optimization that there wasn't a payoff.
Are there too many void *s in D?
|
February 12, 2004 Re: | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | >>The fact that in is not specified can only mean one thing
>
>No, it can mean whatever the programmer's previous language experience (or lack thereof) might suggest.
Isn't this true for any keyword? You have to learn the language, before using it.
|
February 12, 2004 Re: | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | >> I also prefer 'ref' to inout, also i would like to so 'in' dropped as
>nobody
>> is ever going to use it, it is implicit and hence redundant. Its a waste
>of
>> ascii.
>
>That's probably a good idea.
Either I'm stupid or this suggestion was part of my first (or second?) post
here. :confused:
|
February 12, 2004 Re: | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | >Probably too late to worry about this one, alot of people are probably attached to the in/out/inout scheme. What D has now isn't really broken.
D still hasn't reached version 1.0, so this shouldn't be a problem.
|
February 12, 2004 Re: | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | >1b. Minimum-ascii thinking led to the horrible C syntax and butchered semantics that we have today. Remember when you were first learning C? I do. It was awful. Everything was so cryptic.
# include <stdio.h>
# define MAin printf("%d\n"
# define mAIN return 0
# define MaiN {static
# define mAlN ) {if(
# define MA1N char*
# define MAiN (!!(
# define mAiN atoi
# define mAln &1<<
# define MAlN !=3)
# define MAln )&&
# define MAIN int
# define maln --,
# define Maln <<
# define MaIn ++
# define MalN |=
# define MA1n ||
# define malN -1
# define maIN *
# define MaIN =
# define ma1N )
# define Ma1N (
# define Main ;
# define mA1n !
# define MAIn }
# define mA1N ,
MAIN mAIn
Ma1N MAIN
ma1N mA1N
mAiN Ma1N
MA1N ma1N mA1N maIn MaIN malN mA1N ma1n
mA1N maiN Main
MAIN main Ma1N MAIN Ma1n mA1N MA1N maIN
mAin mAlN Ma1n MAlN
mAIN Main maIn MaIn
mA1N Ma1n maln mAin MaIn Main maIn
MaIN mAiN Ma1N Ma1N
Ma1n maln maIN mAin
MaIn ma1N ma1N Main
ma1n MaIN mAiN Ma1N
Ma1N Ma1n maln maIN
mAin MaIn ma1N ma1N
Main mAIn Ma1N mAIn
Ma1N mAIn Ma1N mAIn
Ma1N mAIn Ma1N mAIn Ma1N mAIn
Ma1N mAIn Ma1N mAIn Ma1N mAIn
Ma1N mAIn Ma1N mAIn Ma1N mAIn
Ma1N mAIn Ma1N mAIn Ma1N mAIn
Ma1N Ma1n ma1N
ma1N ma1N ma1N
ma1N ma1N ma1N ma1N ma1N ma1N
ma1N ma1N ma1N ma1N
ma1N ma1N Main MAin
mA1N maiN ma1N Main mAIN Main MAIn MAIN
mAIn Ma1N MAIN mAin ma1N
MaiN MAIN main MaIN malN
Main main MaIn Main mAIN
mA1N maiN MalN Ma1N MAiN
maIn mAln main ma1N
MA1n Ma1N MAiN ma1n
mAln main ma1N MA1n
mAin MAln Ma1N
mA1n MAiN ma1n mAln
main MAln mAin ma1N
ma1N ma1N MAln Ma1N mA1n MAiN maIn
mAln main MAln
Ma1N MAiN ma1n
mAln main ma1N MA1n mAin MAln
Ma1N mA1n MAiN
ma1n mAln main
MAln mAin ma1N
ma1N ma1N ma1N
ma1N ma1N Maln
main mA1N MAiN
ma1n mAln main
MAln mAin ma1N
MA1n MAiN maIn
mAln main MAln
Ma1N MAiN ma1n
mAln main ma1N MA1n
mAin MAln
Ma1N mA1n
MAiN ma1n
mAln main
MAln mAin
ma1N ma1N
ma1N ma1N
Main MAIn
|
Copyright © 1999-2021 by the D Language Foundation