0

(I was asked this question recently.)

I want to use the C++ static_block construct to initialize static field of a class:

static_block {
   myns::foo my_foo;
   auto s = my_foo.from_string("null");
   if (s.good()) {
     std::string bar::transmogrified_foo = my_foo.transmogrify();
   } else {
     std::string bar::transmogrified_foo = "";
   }
}

where transmogrified_foo is declared in the class as:

static std::string transmogrified_foo;

However, I get the following error:

error: definition or redeclaration of 'transmogrified_foo' not allowed inside a function

Do you have suggestion how the static field should be initialized ?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 1
    It's essentially the same question as the beginner question: how come I write `int i = 1; if(something) {int i = 2;} cout< – user253751 Aug 05 '22 at 20:37
  • @user253751: For a lax enough definition of "essentially". – einpoklum Aug 05 '22 at 21:03
  • It's a *really* bad idea to assume that " does this, so will do it that way too.". While you may get lucky, as you have in this case, and get an observable difference - it's quite common that your code seems to work correctly until (sometime in the future) a minor edit causes an unexplained bug (and worse, a bug for an end user who gets grumpy about it, not yourself). JavaScript and C++ are *different* languages because they do things quite differently, even when using the same syntax (the syntax appears the same, the semantics/meaning differs). – Peter Aug 06 '22 at 01:25

1 Answers1

2

You're confusing the definition of the static member with its initialization. See also:

The differences between initialize, define, declare a variable

It seems like you were trying to define your static field, when it has no other definition. Indeed, you can't do that within the body of a function (and a static_block actually invokes a static function).

You could do one of two things:

  1. Split the definition and the initialization of the field - in which case you could initialize in a static block.
  2. Use another way of running a bit of code when defining your field - not a static block.

I would go with option (2.) :

std::string bar::transmogrified_foo = 
   []() {
       myns::foo my_foo;
       auto s = my_foo.from_string("null");
       return s.good() ? my_foo.transmogrify() : "";
   }();

So, you see the static block doesn't really give you any benefit here.

einpoklum
  • 118,144
  • 57
  • 340
  • 684