10

there is something that's bugging me.

In a non-threaded program, is it better to have local static variables(inside methods) or static class members?

In this example:

class C{
public: 
  C(){};
  void foo();
};

void C::foo(){
  static int bar = 0;
  bar++;
  printf("%d\n",bar);
}

Is it considered a bad practice if bar will solely be used in C::foo()?

Manux
  • 3,643
  • 4
  • 30
  • 42

6 Answers6

7

Neither is better. They serve very different use cases

Falmarri
  • 47,727
  • 41
  • 151
  • 191
  • 4
    The beginning of your answer sounds promising, but could you elaborate? – Ilya Kogan Dec 29 '10 at 17:54
  • 12
    @IIyan, the semantics in his code is "print how many times 'foo' was called!". From what one can see in his question, this has nothing to do with state of the class, and so it would be plain wrong to put the variable as a static class member. If however `foo` would be a copy constructor and `bar` would be called `numberOfCopies`, it would be a good candidate for a static class member. So it depends on how it's used. – Johannes Schaub - litb Dec 29 '10 at 17:55
4

I usually try to limit the scope of variables as much as possible, as long as it doesn't become weird or tedious.

If you have 1000 lines of code in class C, of them 100 lines of code in the function foo, any change you do to bar (for example, changing the name or type) requires going over 100 lines of code to make sure the change is OK. If you had bar a static class member, you might have to go over 1000 lines of code, just to make sure bar is not used there. This would be a waste of time.

If you think you might need bar in another function foo2 (for example, when counting call count for foo and foo2 together), you might want to make bar a static class member.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • +1 Minimizing "static" variable scope is important. Global vs. .cpp module vs. class vs. method/function vs. nested { } block. I tend to prefer using .cpp module level static data over being included in a class declaration, because if you stick it in the class header, then clients are now dependent upon an implementation detail. – franji1 Dec 29 '10 at 20:36
2

If it's a public class, a static class member requires editing the header file. This is not always desirable.

Another option is a file-scoped variable, in an anonymous namespace. This is sufficient if you need access only in one method, and if you need it in multiple.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
0

Object-oriented-speaking, bar is part of the state of class C. This is the reason why I usually prefer using fields rather than static local variables.

Ilya Kogan
  • 21,995
  • 15
  • 85
  • 141
  • 1
    state of which object? global variables (statics in this example) are not part of the state of any object, they are part of the global state. – Gene Bushuyev Dec 29 '10 at 18:02
  • 1
    No it isn't. Only non-static members can serve as "state" of an object. – Edward Strange Dec 29 '10 at 18:13
  • -1 You don't know that `bar` is part of the class' state. It may be part of the *member function's* state. In which case, a local static is appropriate. – John Dibling Dec 29 '10 at 18:40
0

Both local and non-local global variables are "bad" by the virtue of being global. But initialization and access for those two cases are different, so the answer which one to use depends on your needs regarding those requirements.

As a side note, dynamic initialization of local variables with static storage duration may not be thread-safe, depending on your compiler. The good news, in C++0x it's guaranteed to be thread-safe.

Gene Bushuyev
  • 5,512
  • 20
  • 19
  • There is noting wrong with global variables. The problem is with globally accessible mutable state. Neither is true here. – Martin York Dec 29 '10 at 18:30
  • @MartinYork, this state is global, mutable and accessible. Any instance of C may change it. – evoskuil Jun 15 '21 at 10:52
  • @evoskuil I was commenting on this answer. The statement: `Both local and non-local global variables are "bad"`. On its own this statement is wrong. The issue (as with the question) is global mutable state. – Martin York Jun 15 '21 at 16:52
  • @evoskuil: That question and answer is over a decade old. Why are you reading zero point answers to questions. – Martin York Jun 15 '21 at 17:00
0

I would consider the use of static members for anything but const values (that aren't eligible for constexpr) to be a bad practice. The scope of a static member or method local is global, it just happens to be accessible only by (all instances of) a class.

Non-const class static is at the top of my list for bad practices. It's worse than simply declaring a global variable - because it's hidden. A singleton class (or even just a class that you construct only once and pass to dependent classes) eliminates this practice.

But otherwise I would recommend exposing the static via a global accessor (with big ugly comments around it). If at any point the code becomes concurrent, you can drop in a critical section.

// Danger, global state.
int inc_bar()
{
    static int bar = 0;
    return bar++;
}

class my_class
{
public:
    my_class()
    {
    }

    void inc()
    {
        printf("%d\n", inc_bar());
    }
};
evoskuil
  • 1,011
  • 1
  • 7
  • 13