www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Two other kinds of static

reply bearophile <bearophileHUGS lycos.com> writes:
Time ago I have half-seriously suggested a "static static", to solve a small
problem I've has in my code. foo is a function template, so even if bar is
static, every instantiation of foo gets a different bar:


auto foo(T)(int x) {
    static bar = ...;
    ...
}


A "static static" means there is only one bar shared for all instances of foo,
this is something I have desired a bit to do:

auto foo(T)(int x) {
    static static bar = ...;
    ...
}


Now I have found a bit of need for another kind of static :-) In C/C++ there
isn't this need because they don't have nest functions as D (GCC supports nest
functions, but they are not used much). An example:


int foo() {
    int bar() {
        static(foo) int[10] spam;
        //...
    }
    // ...
}


That means something like:

int foo() {
    int[10] spam;
    // spam not visible here
    int bar() {
        // use spam here only
    }
    // spam not visible here
}

"spam" is static regarding the bar() function, but it's not static (so it's
automatic) for foo() function. This is sometimes useful because I know how bar
will be called (inside foo), but I don't know how foo() itself will be called
and used, and generally foo() may be a recursive function. So this is wrong
code, I can't set spam as a truly static variable:


int foo() { // recursive
    int bar() { // not recursive
        static int[10] spam; // wrong
        // ...
    }
    
    return bar() + foo();
}

Bye,
bearophile
Jun 04 2011
next sibling parent reply Mehrdad <wfunction hotmail.com> writes:
On 6/4/2011 6:36 AM, bearophile wrote:
 Time ago I have half-seriously suggested a "static static", to solve a small
problem I've has in my code. foo is a function template, so even if bar is
static, every instantiation of foo gets a different bar:


 auto foo(T)(int x) {
      static bar = ...;
      ...
 }


 A "static static" means there is only one bar shared for all instances of foo,
this is something I have desired a bit to do:

 auto foo(T)(int x) {
      static static bar = ...;
      ...
 }


 Now I have found a bit of need for another kind of static :-) In C/C++ there
isn't this need because they don't have nest functions as D (GCC supports nest
functions, but they are not used much). An example:


 int foo() {
      int bar() {
          static(foo) int[10] spam;
          //...
      }
      // ...
 }


 That means something like:

 int foo() {
      int[10] spam;
      // spam not visible here
      int bar() {
          // use spam here only
      }
      // spam not visible here
 }

 "spam" is static regarding the bar() function, but it's not static (so it's
automatic) for foo() function. This is sometimes useful because I know how bar
will be called (inside foo), but I don't know how foo() itself will be called
and used, and generally foo() may be a recursive function. So this is wrong
code, I can't set spam as a truly static variable:


 int foo() { // recursive
      int bar() { // not recursive
          static int[10] spam; // wrong
          // ...
      }

      return bar() + foo();
 }

 Bye,
 bearophile
Why not just put your "static static" variable /outside/?
Jun 04 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Mehrdad:

 Why not just put your "static static" variable /outside/?
Why don't you put your "static" variables outside? Because their name becomes visible by everyone else. Bye, bearophile
Jun 04 2011
parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 4/06/11 8:35 PM, bearophile wrote:
 Mehrdad:

 Why not just put your "static static" variable /outside/?
Why don't you put your "static" variables outside? Because their name becomes visible by everyone else. Bye, bearophile
Well, only by everyone else in the module :) I can see cases where you might want this "static static", but those cases appear to be quite rare, and considering that's it's quite easy to work around, I'm not sure it warrants adding extra complexities to the language. Just my 2 cents.
Jun 04 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 04 Jun 2011 09:36:28 -0400, bearophile <bearophileHUGS lycos.com>  
wrote:

 Time ago I have half-seriously suggested a "static static", to solve a  
 small problem I've has in my code. foo is a function template, so even  
 if bar is static, every instantiation of foo gets a different bar:


 auto foo(T)(int x) {
     static bar = ...;
     ...
 }


 A "static static" means there is only one bar shared for all instances  
 of foo, this is something I have desired a bit to do:

 auto foo(T)(int x) {
     static static bar = ...;
     ...
 }
Just put it outside foo: private static bar = ...; auto foo(T)(int x) { ... }
 Now I have found a bit of need for another kind of static :-) In C/C++  
 there isn't this need because they don't have nest functions as D (GCC  
 supports nest functions, but they are not used much). An example:


 int foo() {
     int bar() {
         static(foo) int[10] spam;
         //...
     }
     // ...
 }


 That means something like:

 int foo() {
     int[10] spam;
     // spam not visible here
     int bar() {
         // use spam here only
     }
     // spam not visible here
 }

 "spam" is static regarding the bar() function, but it's not static (so  
 it's automatic) for foo() function. This is sometimes useful because I  
 know how bar will be called (inside foo), but I don't know how foo()  
 itself will be called and used, and generally foo() may be a recursive  
 function. So this is wrong code, I can't set spam as a truly static  
 variable:
int foo() { static int[10] spam; int bar() { } } I understand you want to limit the accessible namespace, but saying "it can't be done" is not true. It can be done, with proper control over the code. That is, as long as you follow your own rules, outsiders can't break into it. I'd recommend naming the variables in a way that "suggests" the namespace they should be in: int foo() { static int[10] bar_spam; // only used inside bar int bar() { } } -Steve
Jun 06 2011