Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is static block in c or c++? [duplicate]

I want to know that what is static block in c or c++ with an example? I know what is static but what is the difference between static and static block?

like image 285
Abhineet Avatar asked Jul 30 '10 08:07

Abhineet


People also ask

What is static block in C?

There is no concept with the name "static block" in C/C++. Java has it however, a "static block" is an initializer code block for a class which runs exactly once, before the first instance of a class is created.

What is the static block?

In a Java class, a static block is a set of instructions that is run only once when a class is loaded into memory. A static block is also called a static initialization block. This is because it is an option for initializing or setting up the class at run-time.

What is the difference between static block and instance block?

Static blocks can be used to initialize static variables or to call a static method. However, an instance block is executed every time an instance of the class is created, and it can be used to initialize the instance data members.

What is difference between static block and static method?

Static methods belong to the class and they will be loaded into the memory along with the class, you can invoke them without creating an object. (using the class name as reference). Whereas a static block is a block of code with a static keyword. In general, these are used to initialize the static members.


2 Answers

In C++ there is the concept of an anonymous namespace.

foo.cpp:

namespace {
    int x;
    int y;
}

to get the same effect in C

foo.cpp:

static int x;
static int y;

In simple terms the compiler does not export symbols from translation units when they are either declared static or in an anonymous namespace.

like image 61
bradgonesurfing Avatar answered Nov 04 '22 03:11

bradgonesurfing


I found this answer on The Code Project. It involves having an extra static variable, but I believe it is more reliable than bradgonesurfing's answer. Basically, it is this:

class Foo
{
public:
    static int __st_init;
private:
    static int static_init(){
        /* do whatever is needed at static init time */
        return 42;
    }
};
int Foo::__st_init = Foo::static_init();

It also means that, like Java's static blocks, you are not required to ever actually have an instance of class Foo, which is useful when the class can take a lot of data, and you simply need to automagically call something before it loads, not instantiate an extra instance of it. You can test that exact code block. I just compiled it (with a little output from static_init(), and had main() print Foo::__st_init, just to make sure), and it worked just fine.

$g++ -v

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.1-9ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)

EDIT:

Sorry that this is so late, but I tested what bradgonesurfing mentioned:

If you test it my accessing the variable in main "just to make sure" you are ensuring the variable is reachable and thus the variable will be initialized and thus static_init will be called. Are you sure it executes if you dont print Foo::__st_init

I used the following inside main.cpp:

#include <iostream>

using namespace std;

class Foo
{
public:
    static int __st_init;
private:
    static int static_init(){
        /* do whatever is needed at static init time */
        cout << "Hello, World!";
        return 42;
    }
};
int Foo::__st_init = Foo::static_init();

int main(int argc, char** argv)
{
        return 0;
}

I compiled with g++ ./main.cpp -o main and ran it and recieved a friendly "Hello, World!" message on my console. Just to be thorough, I also compiled the same version but without the printing and compiled with g++ ./main.cpp -g -o main. I then ran the executable with gdb and had the following result:

(gdb) break Foo::static_init
Breakpoint 1 at 0x400740: file ./main.cpp, line 12.
(gdb) start
Temporary breakpoint 2 at 0x4006d8: file ./main.cpp, line 19.
Starting program: /home/caleb/Development/test/main-c++ 

Breakpoint 1, Foo::static_init () at ./main.cpp:12
12              return 42;
(gdb) 

Here's a more current version output for g++: g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2

like image 40
Caleb1994 Avatar answered Nov 04 '22 02:11

Caleb1994