Hola,
Se que hace algun tiempo ( quizas dos años ) use un par de funciones de C predefinidas que se ejecutaban antes y después de lanzar la main. No recuerdo cuales son, ni encuentro en sant google. Alguien me puede ayudar ?
Un saludo.
Antes no recuerdo nada, pero tampoco lo veo necesario. Si quieres que algo se ejecute antes del main()... pues ponlo en el main() antes que nada.
Para después tienes
int atexit(void (*func)(void));
Que ejecuta la función que especifiques antes de salir del programa desde cualquier punto (con un exit( -1 ) por ejemplo).
Si lo haces varias veces, al salir se ejecutarían en orden inverso.
Asias sés,
Pero no es la que busco. Concretamente necesito una funcion que se llama después de que se ejecuten los destructores de los objetos. atexit se ejecuta antes.
Nota: creo recordar que empezaba por _ o __ el nombre de la función, y es seguro que hablo de ella ( como mínimo la de arranque ) MChiz en uno de sus post ( q no trataba sobre ese tema, así que por eso me puedo volver loco buscando ).
Un saludo.
No se que función será esa, pero si usas gcc, siempre puedes usar la opción -S para que te devuelva el código en ensamblador y así buscar los últimos calls que se hacen en main.
No se que función será esa, pero si usas gcc, siempre puedes usar la opción -S para que te devuelva el código en ensamblador y así buscar los últimos calls que se hacen en main.
Si hablas de objetos me imagino que usaras c++, entonces lo que puedes hacer es crear una clase estatica global y en su destructor hacer lo que quieras, si tienes mas de una clase estatica esta debe ser la primera en crearse para ser la ultima en destruirse.
Si hablas de objetos me imagino que usaras c++, entonces lo que puedes hacer es crear una clase estatica global y en su destructor hacer lo que quieras, si tienes mas de una clase estatica esta debe ser la primera en crearse para ser la ultima en destruirse.
(ses)
(ses)
Yo lo q pretendo es ejecutar código depués de que se ejecuten los destructores de todos los objetos de la applicación. Creo q tiene que existir algo al respecto predefinido, sin hacer paranoias. Si alguien puede ayudar, lo agradeceré enormemente.
Un saludo.
No es paranoia :lol:, es todos los compiladores se comportan de la misma manera ya que es un estandar la forma de creacion y destruccion de objetos
Cita de: "zupervaca"Si hablas de objetos me imagino que usaras c++, entonces lo que puedes hacer es crear una clase estatica global y en su destructor hacer lo que quieras, si tienes mas de una clase estatica esta debe ser la primera en crearse para ser la ultima en destruirse.
"...una clase estatica global..." O_O
Insisto en que debe haber algun forma prevista.
Ejemplo:
class UltimaClase
{
public:
~UltimaClase()
{
// Haces lo que quieras
}
};
// Esto es una clase estatica global, es decir, accedes a ella desde cualquier parte que se haya incluido
static UltimaClase ultimaClase;
// Mas declaraciones
....
int main()
{
// Esto es un miembro estatico local, es decir, solo se puede acceder a ella dentro de la funcion main
static int pepe = 0;
return 0;
}
Con esto ya te funciona lo que quieres, ahora sigue poniendo caras majete :P
a.- No me llames majete
b.- Que difencia hay entre una clase global, i una clase estatica global ? :ph34r:
Sigo en mis trece... q tiene q haber algo.
Cita de: "Degiik"Yo lo q pretendo es ejecutar código depués de que se ejecuten los destructores de todos los objetos de la applicación. Creo q tiene que existir algo al respecto predefinido, sin hacer paranoias.
No lo hay.
Citara.- No me llames majete
Vale, pero es una simple forma de hablar
Citarb.- Que difencia hay entre una clase global, i una clase estatica global ?
El orden de destruccion, veo que no te has empollado el estandar c++, una clase global no estatica se destruye antes que una clase estatica global.
No se por que preguntas para luego hacer estas cosas.
Cita de: "zupervaca"Citara.- No me llames majete
Vale, pero es una simple forma de hablar
Citarb.- Que difencia hay entre una clase global, i una clase estatica global ?
El orden de destruccion, veo que no te has empollado el estandar c++, una clase global no estatica se destruye antes que una clase estatica global.
No se por que preguntas para luego hacer estas cosas.
CitarEl orden de destruccion, veo que no te has empollado el estandar c++, una clase global no estatica se destruye antes que una clase estatica global
#include <windows.h>
#include <stdio.h>
class a
{
public:
int v;
a(){v=0;}
~a()
{
char s[10];
sprintf (s,"%d",v);
MessageBox (NULL,s,NULL,MB_OK);
}
};
static class b
{
public:
int v;
b(){v=1;}
~b()
{
char s[10];
sprintf (s,"%d",v);
MessageBox (NULL,s,NULL,MB_OK);
}
};
class c
{
public:
int v;
c(){v=2;}
~c()
{
char s[10];
sprintf (s,"%d",v);
MessageBox (NULL,s,NULL,MB_OK);
}
};
a aa;
b bb;
c cc;
void main (void)
{
}
Salida:
2
1
0
CitarNo se por que preguntas para luego hacer estas cosas.
Pregunto porque no se si eres muy bueno, o muy malo. En cualquier caso, tu tono es muy prepotente y sentenciador, y no queria realizar un asociación directa entre lo primero y segundo.
CitarPregunto porque no se si eres muy bueno, o muy malo. En cualquier caso, tu tono es muy prepotente y sentenciador, y no queria realizar un asociación directa entre lo primero y segundo
Es normal que te parezca todo eso si despues de decirte las cosas te ries de mi, lo importante es que te funciona como has podido comprobar.
http://arco.inf-cr.uclm.es/~dvilla/pensar_...++/ch10s01.htmlEn concreto: "1.1.2. Destructores de objetos estáticos"
Umm, creo que aqu� se est�n mezclando conceptos:
CitarSi hablas de objetos me imagino que usaras c++, entonces lo que puedes hacer es crear una clase estatica global
Supongo que te refieres a una instancia est�tica de una clase (por el ejemplo que hay posteriormente). Que yo sepa, no existe el concepto de clase est�tica.
CitarNo es paranoia es todos los compiladores se comportan de la misma manera ya que es un estandar la forma de creacion y destruccion de objetos
El est�ndar define el orden de destrucci�n de objetos no est�ticos. Para objetos globales (o atributos estáticos), no se puede asegurar el orden en el que se destruyen (depende del compilador). En cambio, para objetos est�ticos locales (aquellos definidos dentro de una funci�n), este orden s� est� garantizado.
Citar...una clase global no estatica se destruye antes que una clase estatica global.
De nuevo, suponiendo que hablas de instancias, una variable global es estática, ¿o no?. Si a una variable declarada en el ámbito global se le añade el modificador static entonces pasa a ser "privada" de la unidad de compilación y no tiene que ver con su almacenamiento.
Citarstatic class b
{
public:
int v;
b(){v=1;}
~b()
{
char s[10];
sprintf (s,"%d",v);
MessageBox (NULL,s,NULL,MB_OK);
}
};
"static class" ??? Esto no existe. El ejemplo funciona porque los objetos que creas (aa, bb y cc) no son est�ticos, por lo que se destruyen en el orden inverso en el que est�n declarados. El VS2003 genera este mensaje:
Citarwarning C4091: 'static ' : ignored on left of 'b' when no variable is declared
En definitiva, haciendo uso �nicamente de C++ si tienes objetos est�ticos globales, por ejemplo, con alg�n singleton, no existe ese punto a ejecutar despu�s de todos los destructores de los objetos. Tendr�s que recurrir a alguna funci�n de CRT.
Efectivamente me refiero a una instancia, no me habia fijado que el habia puesto "static class b"
En la web que he puesto y en el apartado que indique habla sobre el orden de destruccion de objetos:
CitarComo la destrucción ordinaria, la destrucción de objetos estáticos se lleva a cabo en orden inverso al de la inicialización. Hay que tener en cuenta que sólo los objetos que han sido construidos serán destruidos. Afortunadamente, las herramientas de desarrollo de C++ mantienen un registro del orden de inicialización y de los objetos que han sido construidos
En todos los compiladores que he usado funciona igual, el primero en crearse es el ultimo en destruirse por que usan una pila o simplemente guardan el orden como indica el quote, no obstante si quieres asegurarte al 100% de que se inicialicen en el orden correcto, para asi, que su destruccion sea en el orden correcto se suele hace el truco de hacer una funcion estatica global por cada clase, que sera llamada por ejemplo desde el main, asi de esta manera indicaras el orden de creacion de los objetos.
El libro de Stroustrup dice que eso sólo se garantiza para objetos estáticos locales (definidos dentro de una función). Ahora bien, para objetos estáticos globales o atributos estáticos de una clase, eso no está garantizado, especialmente, cuando los objetos globales se definen en varias unidades de compilación.
No tengo el estándar pero recuerdo que la implementacón típica del patrón Singleton sufre este problema. Por ello hay publicada una "gem" que se basa en una template y algo de aritmética de punteros. Podría buscar el enlace si es necesario.
Ahora bien, si como dices funciona bien en los compiladores que has probado, pues nada, pero creo que no habría que "fiarse" de eso.
Cita de: "hotcamus"No tengo el estándar pero recuerdo que la implementacón típica del patrón Singleton sufre este problema. Por ello hay publicada una "gem" que se basa en una template y algo de aritmética de punteros. Podría buscar el enlace si es necesario.
Así es, pero el hack que utiliza el autor en dicha gem no es portable:
// ...
static T* m_Singleton;
// ...
// Dentro del constructor...
int offset = (int)(T*)1 - (int)(Singleton *)(T*)1;
m_Singleton = (T*)((int)this + offset);
// ...
El código del constructor asume que el tamaño de un puntero es el mismo que el de un int, lo cual no está asegurado en C++, y además no almacena información adicional necesaria para representar los punteros (y con ello asegurar un correcto comportamiento multiplataforma). Con un
static_cast el asunto se soluciona y el código se vuelve de pronto portable, más agradable de leer y más fácil de entender. :)
Yo la solucion que hago si quiero que los objetos se inicialicen en un orden concreto usando el singleton es esto:
#include <stdio.h>
template <class TYPE> class Singleton
{
public:
TYPE *operator -> ()
{
return &this->object;
}
static TYPE object;
};
template <class TYPE> TYPE Singleton<TYPE>::object;
class a
{
public:
a()
{
fprintf( stderr, "Constructor de A\r\n" );
}
~a()
{
fprintf( stderr, "Destructor de A\r\n" );
}
void hola()
{
}
};
class b
{
public:
b()
{
fprintf( stderr, "Constructor de B\r\n" );
}
~b()
{
fprintf( stderr, "Destructor de B\r\n" );
}
void hola()
{
}
};
int main ()
{
Singleton<a> aa;
Singleton<b> bb;
aa->hola();
bb->hola();
return 0;
}
Cambiando el orden dentro del main de "Singleton
aa;" y "Singleton bb;" inicializaremos uno u otro antes, de esta manera incluso en aplicaciones multihilo se crea una sola instancia de una clase y en el orden correcto para su inicializacion y destruccion, se sobre entiende que los multiples hilos del app se crean despues de indicar todos los singletons
Pues por lo que yo entiendo, en este ejemplo precisamente no est� garantizado el orden de inicializaci�n ya que las variables est�ticas son miembros de la clase.
Si cambiases el atributo est�tico a una variable local s� que estar�a garantizado:
TYPE *operator -> ()
{
static TYPE object;
return &object;
}
En este caso, las dos llamadas que tienes en el main determinar�an el orden de construcci�n y, por lo tanto, el de destrucci�n.
Buff ¿por que no pruebas el ejemplo en todos los compiladores que quieras y lo dejamos? es que creo que es perder el tiempo intentar demostrar algo que funciona en el 100% de los casos y de los compiladores, es que seria lo de siempre, pondria mil links, tu pondrias otros y estariamos en un sin acabar.
Cita de: "zupervaca"Buff ¿por que no pruebas el ejemplo en todos los compiladores que quieras y lo dejamos? es que creo que es perder el tiempo intentar demostrar algo que funciona en el 100% de los casos y de los compiladores, es que seria lo de siempre, pondria mil links, tu pondrias otros y estariamos en un sin acabar.
Solo por que te funcione no significa que este bien hecho.
Cita de: "Jare"Cita de: "zupervaca"Buff ¿por que no pruebas el ejemplo en todos los compiladores que quieras y lo dejamos? es que creo que es perder el tiempo intentar demostrar algo que funciona en el 100% de los casos y de los compiladores, es que seria lo de siempre, pondria mil links, tu pondrias otros y estariamos en un sin acabar.
Solo por que te funcione no significa que este bien hecho.
Por lo mismo que por que no se sepa por que funciona no significa que este mal hecho.
El por que funciona es simple, la clase singleton alberga un miembro estatico, pero la instancia de la clase en si no es estatica por lo que al indicarlas en la funcion main se asignan como memoria automatica, es decir, en la pila, y la pila tiene un orden muy estricto, el primero en destruirse es el ultimo en crearse, y ya que el estandar c++ indica que las instancias de las clases solo se inicializan cuando son llamadas por primera vez el orden se vuelve correcto, no hay mas, ahora si sigueis sin entenderlo abandono por que ya cansa tener que explicar las cosas.
Cita de: "zupervaca"Por lo mismo que por que no se sepa por que funciona no significa que este mal hecho.
Cuando el autor no sabe explicar por qué funciona, tampoco puede GARANTIZAR que vaya a seguir funcionando mañana, y por tanto su trabajo no está bien hecho (a no ser que te paguen por hacer algo y solo te exijan que funcione "hoy" ;)). Y, como vamos a ver más abajo, cuando la razon por la que funciona es "implementation dependent" o "por pura casualidad", entonces ESTA mal hecho, sepas o no sepas por qué.
Cita de: "zupervaca"El por que funciona es simple, la clase singleton alberga un miembro estatico, pero la instancia de la clase en si no es estatica por lo que al indicarlas en la funcion main se asignan como memoria automatica, es decir, en la pila, y la pila tiene un orden muy estricto, el primero en destruirse es el ultimo en crearse, y ya que el estandar c++ indica que las instancias de las clases solo se inicializan cuando son llamadas por primera vez el orden se vuelve correcto
Ni de coña.
"For the static member to exist, it is not necessary that any objects of the class type exist"
Las variables estáticas de una funcion son inicializadas la primera vez que se ejecuta la función, ni antes ni despues. Para las estáticas de clase eso no es aplicable, porque ni siquiera hace falta que exista una instancia de la clase para que la estática de esa clase exista.
"Initialization of global static objects in a translation unit. This may occur either before entry to main or before the first use of any function or object in the object's translation unit."
Las variables estáticas de una clase se pueden inicializar mucho antes y en un orden no definido por el estándar. Lo curioso es que los templates en general ni siquiera viven en una translation unit concreta, sino (generalmente) como multiples en una amalgama de "translation units" en las que se usa ese template, y que el linker se ocupa de fundir en una sola copia.
La presencia de las instancias en la pila no tiene NADA que ver. La realidad? Funciona en tu ejemplo solamente por la forma en que el compilador / linker generan el código asociado al template en ese caso concreto. Tu ejemplo es tremendamente fácil de destrozar:
#include <stdio.h>
template <class TYPE> class Singleton
{
static TYPE object;
public:
TYPE *operator -> () { return &this->object; }
};
template <class TYPE> TYPE Singleton<TYPE>::object;
struct A { A() { puts("A::A()"); } ~A() { puts("A::~A()"); } void f() {puts("A::f()"); } };
struct B { B() { puts("B::B()"); } ~B() { puts("B::~B()"); } void f() {puts("B::f()"); } };
void f()
{
Singleton<B> b;
puts("f()");
b->f();
}
int main()
{
Singleton<A> a;
Singleton<B> b;
a->f();
b->f();
f();
return 0;
}
Y la salida de ese programa es:
B::B()
A::A()
A::f()
B::f()
f()
B::f()
A::~A()
B::~B()
Como puedes ver, el orden de los singletons en main() es A y luego B, sin embargo las llamadas a los constructores de esas clases ocurren en orden inverso. Por qué? Porque lo que dices simplemente NO ES CIERTO, aunque en determinados casos funcione por casualidad. Mejor dejarse de filigranas que ni funcionan ni responden a una regla establecida y estandarizada. Globales con inicialización explÃcita y a vivir que son dos dÃas.
PD: Joer que destrozo hace el foro con los acentos y tal. :(
¿Por casualidad era esto lo que buscabais?
https://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/gcc/Executing-code-before-main.html