Qu’est-ce qu’un bloc statique en c ou c ++?

Je veux savoir ce qui est bloc statique en c ou c ++ avec un exemple? Je sais ce qui est statique mais quelle est la différence entre un bloc statique et statique?

Une autre solution consiste à rechercher l’analogie d’un bloc statique en Java. Un bloc de code qui est exécuté lorsque l’application est chargée. C ++ n’existe pas, mais il est possible de la simuler en utilisant le constructeur d’un object statique.

foo.cpp: struct StaticBlock { StaticBlock(){ cout << "hello" << endl; } } static StaticBlock staticBlock; void main(int, char * args[]){ } 

TOUTEFOIS. J'ai été mordu par cela auparavant car c'est un cas subtil du standard C ++. Si l'object statique n'est accessible par aucun code appelé par main, le constructeur de l'object statique peut être appelé ou non.

J'ai trouvé qu'avec gcc, hello obtiendra une sortie et avec Visual Studio, ce ne sera pas le cas.

J’ai trouvé cette réponse sur The Code Project. Cela implique d’avoir une variable statique supplémentaire, mais je pense qu’elle est plus fiable que la réponse de bradgonesurfing. En gros, c’est ceci:

 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(); 

Cela signifie également que, à l’instar des blocs statiques de Java, vous n’êtes pas obligé d’avoir une instance de la class Foo , ce qui est utile lorsque la classe peut prendre beaucoup de données et que vous devez simplement appeler quelque chose avant de charger, sans le charger. instancier une instance supplémentaire de celle-ci. Vous pouvez tester ce bloc de code exact. Je viens de le comstackr (avec un peu de sortie de static_init (), et j’avais main () print Foo :: __ st_init, juste pour être sûr), et cela a bien fonctionné.

 $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) 

MODIFIER:

Désolé que ce soit si tard, mais j’ai testé ce que bradgonesurfing a mentionné:

Si vous le testez en accédant à la variable principale, vous devez vous assurer que la variable est accessible et que la variable sera initialisée et que static_init sera appelé. Etes-vous sûr qu’il s’exécute si vous n’imprimez pas Foo :: __ st_init

J’ai utilisé les éléments suivants dans main.cpp:

 #include  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; } 

J'ai compilé avec g++ ./main.cpp -o main et l' g++ ./main.cpp -o main exécuté pour recevoir un sympathique "Hello, World!" message sur ma console. Juste pour être complet, j'ai aussi compilé la même version mais sans l'impression et compilé avec g++ ./main.cpp -g -o main . J'ai ensuite exécuté l'exécutable avec gdb et obtenu le résultat suivant:

 (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) 

Voici une version plus récente de la version pour g ++: g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2

Il n’y a pas de concept appelé “bloc statique” en C / C ++. Java l’a cependant, un “bloc statique” est un bloc de code d’initialisation pour une classe qui s’exécute exactement une fois, avant la création de la première instance d’une classe. Le concept de base ‘Fonction exécutée exactement une fois’ peut être simulé en C / C ++ avec une variable statique, par exemple:

 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; } ... } 

Ce n’est pas thread-safe cependant . Bien fonctionner en présence de plusieurs threads peut parfois être difficile et délicat.

Bien que C ++ ne comporte pas de blocs statiques dans le langage, vous pouvez les implémenter sans que vous (en tant qu’utilisateur) ayez à utiliser des classes ou des espaces de noms, et pouvez écrire:

 #include "static_block.h" static_block { int x = 1; int y = 2; int z = x+y; std::cout << z << " = " << x " << " + " << y << "\n"; } 

ou ce que vous voulez d'autre. Vous ne pouvez pas avoir ces classes, cependant, juste à la scope du fichier. Voir une description détaillée de ceux-ci dans ma réponse à une question connexe, ainsi que le code de static_block.h ici .

Remarque: Cela ne nécessite pas C ++ 11 et fonctionnera bien avec les anciens compilateurs.

En C ++, il y a le concept d’un espace de noms anonyme.

 foo.cpp: namespace { int x; int y; } 

pour obtenir le même effet en C

 foo.cpp: static int x; static int y; 

En termes simples, le compilateur n’exporte pas les symboles des unités de traduction lorsqu’elles sont déclarées statiques ou dans un espace de noms anonyme.