4

I have a method / function:

void foo() {

  static const std::string strSQLQuery = "SELECT ... ";
  // or maybe
  const std::string strSQLQuery = "SELECT ... "; 

  // some operations on strSQLQuery
  // i.e. concatenating with WHERE, etc.:
  const std::string strSQL = strSQLQuery + strWHERE;

  doSthOnDataBase(strSQL);
}

(SQL is only an example)

  1. static const will be initialized only once, but persists in memory until the process ends.
  2. const will be initialized every time foo() is run, but the memory (stack) is freed when the {} block ends.

On the other hand, the string "SELECT ... " has to be still hardcoded in the program code. And it's no matter if we use 1. or 2.

So which approach is better? Using static const std::string or only const std::string?

Or maybe there's no one answere, because it depends how I want to use foo() -- call it 1000 times per second (then I don't want to initialize a variable every time) or call it 1000 times per month (then I don't care).

(I've read Question Difference between static const char* and const char* and especially answer https://stackoverflow.com/a/2931146/945183, but they apply to const char*.)

18
  • 7
    You seems to have already outlined the pros and the cons of each solution. Hint: There's no absolute better. Commented Jan 24, 2014 at 10:20
  • Note that your program takes a lock when you have a static like this. Commented Jan 24, 2014 at 10:41
  • I would go for the static const because it requires less memory (stack is a very expensive thing to waste) and it basically has the same effect. As a side note, it's very uncommon to have a const define in a method you usually define it globally of as a member of a structure... Commented Jan 24, 2014 at 11:01
  • 1
    @Pandrei: wat. A static string means your code will explode if used in a multithreaded context. A non-static thread means that a few bytes are put on the stack, and the rest on the heap. I have no clue what you are talking about wrt. "stack memory is expensive to waste". Commented Jan 24, 2014 at 11:37
  • 1
    You may use const char* const strSQLQuery = "SELECT ... ". Commented Jan 24, 2014 at 12:55

4 Answers 4

2

Profile it. Chances are, the trip to the database so utterly dwarfs the initialization cost of the strings that it doesn't matter.

And as has been pointed out, local statics are not thread-safe on all compilers. They are in GCC, and C++11 requires them to be, but it took Microsoft until VS2013 to actually implement this.

Sign up to request clarification or add additional context in comments.

2 Comments

It took MS until VS2013 to properly implement some of C++11. They're still not quite there yet...
I know, that the weTeim's answer is similar to this one, but Sebastian ,,went to the point'' better, IMHO, and did not repeat thoughts I included in my Question.
1

Well if a member variable, static const is safe so long as you don't intentionally defeat the const part by casting. But from your linked comments a local variable is different:

A local static variable is initialized the first time its definition is encountered, but not destructed when the function exits. So it keeps its value between invocations of the function.

To make this safe, gcc emits locking to protect the initialization but MS C++ does not as described here, so this can be either safe or not depending on the compiler and even if supposedly safe can have inimical side effects.

The tradeoff here seems to be efficiency versus maintainability. Is that extra little speed worth the possibility of introducing some subtle error. While researching this, I've come full circle on my opinion now, I'd say usually no. Especially since in this case it's a simple string initialization followed up by a lengthly database call.

Comments

0

As I known "static" is not necessary in your case. 1) When you declare and define a const variable, compiler has a chance to replace all occurrences with the value you assigned, like following:

const int var = 9;
int b = sqrt( var );

will become

int b = sqrt( 9 );

This behaves just like #define in C style. If this is what you want, then you already have it without "static".

2) As others told, static variables will remain existence even after foo() returns. I suppose this is not your objective

1 Comment

std::string is dynamically initialized and user-defined. Good luck finding a compiler doing constant propagation on that.
0

Static non-primitive locals (const or not) do atomic read on every function call (initialization flag). They are thread safe (speaking of GCC) only when requested specifically via a compiler flag. The string strSQL constructed at run-time will be much more of a performance hit (because of heap allocation) than static initialization caused atomic read.

The fastest would be something like this:

void call(std::string const& where) {
    static char prefix[] = "SELECT ...";

    std::string strSQL;
    strSQL.reserve(sizeof(prefix)/sizeof(char) + strWHERE.size()); 
    strSQL.append(prefix, sizeof(prefix)/sizeof(char)).append(strWHERE);
    ...
}

Whether you need to sacrifice readability for speed is another question.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.