问题
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?
回答1:
Another alternative is that you might be looking for the analogy of a static block in Java. A block of code that is run when the application is loaded. There is no such thing in C++ but it can be faked by using the constructor of a static object.
foo.cpp:
struct StaticBlock {
StaticBlock(){
cout << "hello" << endl;
}
}
static StaticBlock staticBlock;
void main(int, char * args[]){
}
HOWEVER. I've been bitten by this before as it's a subtle edge case of the C++ standard. If the static object is not reachable by any code called by main the constructor of the static object may or may not be called.
I found that with gcc hello will get output and with visual studio it will not.
回答2:
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
回答3:
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. The basic concept 'stuff that runs exactly once' can simulated in C/C++ with a static variable, for example:
int some_function(int a, int b)
{
static bool once=true;
if (once)
{
// this code path runs only once in the program's lifetime
once=false;
}
...
}
This is not thread-safe however. Getting this working right in the presence of multiple threads can be difficult and tricky sometimes.
回答4:
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.
回答5:
While indeed, C++ does not have static blocks as part of the language, you can implement static blocks without you (as a user) having to use any classes or namespaces, and can write:
#include "static_block.h"
static_block {
int x = 1;
int y = 2;
int z = x+y;
std::cout << z << " = " << x " << " + " << y << "\n";
}
or whatever else you want. You can't have those within classes, though, just at file scope. See a detailed description of these in my answer to a related question, and the code for static_block.h
here.
Note: This does not require C++11 and will work well with old compilers.
来源:https://stackoverflow.com/questions/3370004/what-is-static-block-in-c-or-c