www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - static static

reply bearophile <bearophileHUGS lycos.com> writes:
When I convert a function to a templated function (for example because I know
the value of an argument at compile time, so using a template gives me a poor's
man partial compilation) the static variables get duplicated for each instance
of the function template, and I may need to use true global variables/constants
(but if you use link-time optimization then LDC is able to remove such shared
constants).
So I was thinking about a "static static" attribute that avoid moving the
statics to globals. Is this a useless idea?

Bye,
bearophile
Nov 10 2009
next sibling parent BCS <none anon.com> writes:
Hello bearophile,

 When I convert a function to a templated function (for example because
 I know the value of an argument at compile time, so using a template
 gives me a poor's man partial compilation) the static variables get
 duplicated for each instance of the function template, and I may need
 to use true global variables/constants (but if you use link-time
 optimization then LDC is able to remove such shared constants).
 
 So I was thinking about a "static static" attribute that avoid moving
 the statics to globals. Is this a useless idea?
 
 Bye,
 bearophile

you can kida cheet with a template scope variable template Foo(T...) // unique var for each set of args. { int bar; }
Nov 10 2009
prev sibling parent reply Yigal Chripun <yigal100 gmail.com> writes:
bearophile wrote:
 When I convert a function to a templated function (for example
 because I know the value of an argument at compile time, so using a
 template gives me a poor's man partial compilation) the static
 variables get duplicated for each instance of the function template,
 and I may need to use true global variables/constants (but if you use
 link-time optimization then LDC is able to remove such shared
 constants). So I was thinking about a "static static" attribute that
 avoid moving the statics to globals. Is this a useless idea?
 
 Bye, bearophile

Regardless of usefulness (or good design) of such variables, this sounds extremely dangerous. The compiler must not change semantics of the program based on optimization. optimizing away such variables most definitely alters the semantics. I wonder, how do other languages treat static variables inside templated functions?
Nov 10 2009
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Yigal Chripun:

 Regardless of usefulness (or good design) of such variables, this sounds
 extremely dangerous. The compiler must not change semantics of the
 program based on optimization. optimizing away such variables most
 definitely alters the semantics.

Maybe you have misunderstood, or I have explained the things badly. So I explain again. I have seen that LDC (when it performs link-time optimization, that's not done in all situations) keeps just one copy of constants inside the binary even if such constants are present in more than one template instance. In the situations where LTO is available I think this doesn't cause problems. Then I am half-seriously proposing a syntax like: T foo(T)(T x) { static static int y; // ... } Where the y is now static to (shared among) all instances of the templated function foo. This may be a little error-prone and maybe not that useful, but again here the compiler doesn't change the semantics of the program, because using a double static keyword the programmer has stated such intention. Bye, bearophile
Nov 10 2009
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 What's the advantage over:
 
 static int y;
 
 T foo(T)(T x) {
     // ...
 }

That the global name space is kept clean, the "y" name can be seen only inside foo. Reducing the visibility of names is useful to keep things tidy. (Inside normal functions in D static has just that purpose). Bye, bearophile
Nov 10 2009
next sibling parent Walter Bright <newshound1 digitalmars.com> writes:
bearophile wrote:
 Steven Schveighoffer:
 
 What's the advantage over:
 
 static int y;
 
 T foo(T)(T x) { // ... }

That the global name space is kept clean, the "y" name can be seen only inside foo. Reducing the visibility of names is useful to keep things tidy. (Inside normal functions in D static has just that purpose).

struct MyNameSpace { static int y; T foo(T)(T x) { ... } }
Nov 10 2009
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 Doesn't static do that already?  I mean keep y within the module  
 namespace.  Sure, it's visible to other functions in foo's module, but not  
 the global namespace.  Or does that not work in D...

I think that 'private' is able to keep a name private to a module... But I put lot of stuff in certain D modules, so I'd like to reduce the scope of the name to something smaller of a whole module. (Walter has shown how to use a struct for this). Bye, bearophile
Nov 12 2009
prev sibling parent reply Yigal Chripun <yigal100 gmail.com> writes:
bearophile wrote:
 Yigal Chripun:
 
 Regardless of usefulness (or good design) of such variables, this sounds
 extremely dangerous. The compiler must not change semantics of the
 program based on optimization. optimizing away such variables most
 definitely alters the semantics.

Maybe you have misunderstood, or I have explained the things badly. So I explain again. I have seen that LDC (when it performs link-time optimization, that's not done in all situations) keeps just one copy of constants inside the binary even if such constants are present in more than one template instance. In the situations where LTO is available I think this doesn't cause problems. Then I am half-seriously proposing a syntax like: T foo(T)(T x) { static static int y; // ... } Where the y is now static to (shared among) all instances of the templated function foo. This may be a little error-prone and maybe not that useful, but again here the compiler doesn't change the semantics of the program, because using a double static keyword the programmer has stated such intention. Bye, bearophile

Oh. ok. I seems I completely misunderstood you. It wasn't clear to me before that your were talking about constants. Of course it's perfectly OK to optimize _constants_ like that. IMO, static is harmful and should be avoided. some newer languages recognize this and completely remove this from the language. I'd like to see D going in that path rather than adding even more ways to use static. regarding your concrete proposal - as others said, you can use global variables for that or put this inside a struct if you want to limit the scope.
Nov 11 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Yigal Chripun wrote:
 bearophile wrote:
 Yigal Chripun:

 Regardless of usefulness (or good design) of such variables, this sounds
 extremely dangerous. The compiler must not change semantics of the
 program based on optimization. optimizing away such variables most
 definitely alters the semantics.

Maybe you have misunderstood, or I have explained the things badly. So I explain again. I have seen that LDC (when it performs link-time optimization, that's not done in all situations) keeps just one copy of constants inside the binary even if such constants are present in more than one template instance. In the situations where LTO is available I think this doesn't cause problems. Then I am half-seriously proposing a syntax like: T foo(T)(T x) { static static int y; // ... } Where the y is now static to (shared among) all instances of the templated function foo. This may be a little error-prone and maybe not that useful, but again here the compiler doesn't change the semantics of the program, because using a double static keyword the programmer has stated such intention. Bye, bearophile

Oh. ok. I seems I completely misunderstood you. It wasn't clear to me before that your were talking about constants. Of course it's perfectly OK to optimize _constants_ like that. IMO, static is harmful and should be avoided. some newer languages recognize this and completely remove this from the language. I'd like to see D going in that path rather than adding even more ways to use static. regarding your concrete proposal - as others said, you can use global variables for that or put this inside a struct if you want to limit the scope.

One option that hasn't been mentioned: private ref int myInt() { static int theInt; return theInt; } void fun(T)(T arg) { ... use myInt() ... } Andrei
Nov 11 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Bill Baxter wrote:
 On Wed, Nov 11, 2009 at 1:16 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 
 One option that hasn't been mentioned:

 private ref int myInt() {
    static int theInt;
    return theInt;
 }

 void fun(T)(T arg) {
    ... use myInt() ...
 }

Is that a joke? That just replaces global symbol theInt with global symbol myInt. I don't see the win. --bb

Forgot to mention that the function gives you the opportunity to initialize the object in the general case. Andrei
Nov 11 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 10 Nov 2009 16:15:26 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Yigal Chripun:

 Regardless of usefulness (or good design) of such variables, this sounds
 extremely dangerous. The compiler must not change semantics of the
 program based on optimization. optimizing away such variables most
 definitely alters the semantics.

Maybe you have misunderstood, or I have explained the things badly. So I explain again. I have seen that LDC (when it performs link-time optimization, that's not done in all situations) keeps just one copy of constants inside the binary even if such constants are present in more than one template instance. In the situations where LTO is available I think this doesn't cause problems. Then I am half-seriously proposing a syntax like: T foo(T)(T x) { static static int y; // ... } Where the y is now static to (shared among) all instances of the templated function foo. This may be a little error-prone and maybe not that useful, but again here the compiler doesn't change the semantics of the program, because using a double static keyword the programmer has stated such intention.

What's the advantage over: static int y; T foo(T)(T x) { // ... } -Steve
Nov 10 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Tue, Nov 10, 2009 at 1:15 PM, bearophile <bearophileHUGS lycos.com> wrot=
e:
 Yigal Chripun:

 Regardless of usefulness (or good design) of such variables, this sounds
 extremely dangerous. The compiler must not change semantics of the
 program based on optimization. optimizing away such variables most
 definitely alters the semantics.

Maybe you have misunderstood, or I have explained the things badly. So I =

 I have seen that LDC (when it performs link-time optimization, that's not=

even if such constants are present in more than one template instance. In = the situations where LTO is available I think this doesn't cause problems.
 Then I am half-seriously proposing a syntax like:
 T foo(T)(T x) {
 =A0static static int y;
 =A0// ...
 }

 Where the y is now static to (shared among) all instances of the template=

but again here the compiler doesn't change the semantics of the program, b= ecause using a double static keyword the programmer has stated such intenti= on. Make it "super static" and I'm sold. :-) Just kidding. It's never occurred to me to want something like that. I guess I'd probably just use a global variable. And maybe that's for the better since it screams out more clearly that something strange is going on. And maybe gets the developer to rethink the design one more time before going down that path. --bb
Nov 10 2009
prev sibling next sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Yigal Chripun wrote:
 I wonder, how do other languages treat static variables inside templated 
 functions?

C++ generates a different variable for each instantiation.
Nov 10 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Wed, Nov 11, 2009 at 1:16 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

 One option that hasn't been mentioned:

 private ref int myInt() {
 =A0 =A0static int theInt;
 =A0 =A0return theInt;
 }

 void fun(T)(T arg) {
 =A0 =A0... use myInt() ...
 }

Is that a joke? That just replaces global symbol theInt with global symbol myInt. I don't see the win. --bb
Nov 11 2009
prev sibling next sibling parent Bill Baxter <wbaxter gmail.com> writes:
On Wed, Nov 11, 2009 at 1:36 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 Bill Baxter wrote:
 On Wed, Nov 11, 2009 at 1:16 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 One option that hasn't been mentioned:

 private ref int myInt() {
 =A0 static int theInt;
 =A0 return theInt;
 }

 void fun(T)(T arg) {
 =A0 ... use myInt() ...
 }

Is that a joke? =A0That just replaces global symbol theInt with global symbol myInt. =A0I don't see the win. --bb

Forgot to mention that the function gives you the opportunity to initiali=

 the object in the general case.

Ah, ok. I thought you were proposing that as another way to limit the scope of the variable. --bb
Nov 11 2009
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 10 Nov 2009 16:56:11 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Steven Schveighoffer:

 What's the advantage over:

 static int y;

 T foo(T)(T x) {
     // ...
 }

That the global name space is kept clean, the "y" name can be seen only inside foo. Reducing the visibility of names is useful to keep things tidy. (Inside normal functions in D static has just that purpose).

Doesn't static do that already? I mean keep y within the module namespace. Sure, it's visible to other functions in foo's module, but not the global namespace. Or does that not work in D... -Steve
Nov 12 2009