Personnellement, je réalise mes programmes avec DELPHI (langage Pascal de
BORLAND) où sont définis des "tableaux dynamiques". Ce sont des tableaux
dont on peut fixer la taille (le nombre d'éléments) à l'exécution.
J'utilise ce type de tableaux pour échanger des infos entre un programme et
des DLL.
Existe-t-il l'équivalent, pour ne pas dire la même chose, dans d'autres
langages, notamment le C++ de chez Microsoft.
Sinon, comment faites-vous pour échanger entre .exe et .dll quand vous ne
connaissez pas à la compilation la taille des infos à échanger ;le nombre de
pixels de l'image en cours de traitement par exemple.
C'est les nazes qui programment sans vérifier les retours de fonctions...
soit 99% des programmeurs... Tu vérifies EN PERMANENCE dans ton code le retour de new ? Que c'est lourd !
??? Bah, à peine que je vérifie les valeurs retournées par les fonctions ! Et après ont s'étonne que les programmes plantent... Rien d'étonnant si les 99% des programmeurs raisonnent comme toi.
Dis-moi, et si ton new() plante, puisque tu ne vérifie pas, je suis curieux de savoir comment tu poursuis ton programme...
Un échec de new est sensé lancer une exception, qui n'a pas besoin d'être testé explicitement à l'endroit du new, mais peut-être traitée ailleur. Bien entendu, pour que ça se passe bien, il faut que le reste du programme soit bien écrit pour ne pas causer de problème lors de la remontée de l'exception dans la pile d'appels.
-- Loïc
AMcD® wrote:
Alexandre wrote:
bonjour,
C'est les nazes qui programment sans vérifier les retours de
fonctions...
soit 99% des programmeurs... Tu vérifies EN PERMANENCE dans ton code
le retour de new ? Que c'est lourd !
??? Bah, à peine que je vérifie les valeurs retournées par les fonctions !
Et après ont s'étonne que les programmes plantent... Rien d'étonnant si les
99% des programmeurs raisonnent comme toi.
Dis-moi, et si ton new() plante, puisque tu ne vérifie pas, je suis curieux
de savoir comment tu poursuis ton programme...
Un échec de new est sensé lancer une exception, qui n'a pas besoin
d'être testé explicitement à l'endroit du new, mais peut-être traitée
ailleur. Bien entendu, pour que ça se passe bien, il faut que le reste
du programme soit bien écrit pour ne pas causer de problème lors de la
remontée de l'exception dans la pile d'appels.
C'est les nazes qui programment sans vérifier les retours de fonctions...
soit 99% des programmeurs... Tu vérifies EN PERMANENCE dans ton code le retour de new ? Que c'est lourd !
??? Bah, à peine que je vérifie les valeurs retournées par les fonctions ! Et après ont s'étonne que les programmes plantent... Rien d'étonnant si les 99% des programmeurs raisonnent comme toi.
Dis-moi, et si ton new() plante, puisque tu ne vérifie pas, je suis curieux de savoir comment tu poursuis ton programme...
Un échec de new est sensé lancer une exception, qui n'a pas besoin d'être testé explicitement à l'endroit du new, mais peut-être traitée ailleur. Bien entendu, pour que ça se passe bien, il faut que le reste du programme soit bien écrit pour ne pas causer de problème lors de la remontée de l'exception dans la pile d'appels.
-- Loïc
AMcD®
> Bien entendu, pour que ça se passe bien, il faut que le reste du programme soit bien écrit pour ne pas causer de problème lors de la remontée de l'exception dans la pile d'appels.
Oui, c'est exactement ce point dont je doute :-)
-- AMcD®
http://arnold.mcdonald.free.fr/
> Bien entendu, pour que ça se passe bien, il faut que le reste
du programme soit bien écrit pour ne pas causer de problème lors de la
remontée de l'exception dans la pile d'appels.
> Bien entendu, pour que ça se passe bien, il faut que le reste du programme soit bien écrit pour ne pas causer de problème lors de la remontée de l'exception dans la pile d'appels.
Oui, c'est exactement ce point dont je doute :-)
-- AMcD®
http://arnold.mcdonald.free.fr/
Loïc Joly
AMcD® wrote:
Loïc Joly wrote:
Si tu alloue un tableau d'octets, puis que tu fais croire à ton compilateur que tu as des objets à l'intérieur en castant, tu as alors un comportement indéfini.
Ben ça dépend de quel compilo tu utilises, de quel genre de code tu écris. Moi, en C ou ASM, il m'arrive souvent de déclarer simplement une zone de mémoire et... de choisir ensuite si c'est des BYTE, WORD, LONG, objets, caractères ou je ne sais quoi. Cela dépend de tellement de choses...
Je rappelle que le sujet auquel je répond était la création de tableaux dynamiques en C++, et du choix entre new ou malloc.
Il est clair qu'en C, le problème ne se pose pas, puisque ni objets ni new n'existent. Par contre, je ne connais aucun compilateur C++ où ça ne poserait pas de problème.
La programmation c'est pas un art guidé par des dogmes et des oeillères. Tu ne peux pas dire c'est comme ça et pas autrement. Il y a tellement de domaines d'application, de domaines, de contextes particuliers...
Le C++ (le C aussi) sont des langages normés. Même s'il y a toujours des écarts entre les normes et leurs implémentations, il y a des cas que l'on retrouve partout.
Ce n'est pas être dogmatique ou avoir des oeillère que de dire que si on écrit int a=1+1; alors a vaudra 2.
Ce n'est pas plus être dogmatique que de dire que int a=1/0; provoquera une erreur, et qu'il ne faut pas l'écrire.
Ce n'est pas plus être dogmatique que de dire que dans le cas général (c'est à dire si C n'est pas un POD),
C* c = (C*) malloc(sizeof(C)); C->toto();
Constituera une erreur de code, et qu'il ne faut pas l'écrire.
Au passage, les compilos font ça souvent hein, regarde les unions en C/C++ :-)
Pas besoin de regarder, c'est tout vu, et ça conforte mon point de vue. Là aussi, mettre un objet autre qu'un POD dans une union est illégal en C++.
-- Loïc
AMcD® wrote:
Loïc Joly wrote:
Si tu alloue un tableau d'octets, puis que tu fais croire à ton
compilateur que tu as des objets à l'intérieur en castant, tu as alors
un comportement indéfini.
Ben ça dépend de quel compilo tu utilises, de quel genre de code tu écris.
Moi, en C ou ASM, il m'arrive souvent de déclarer simplement une zone de
mémoire et... de choisir ensuite si c'est des BYTE, WORD, LONG, objets,
caractères ou je ne sais quoi. Cela dépend de tellement de choses...
Je rappelle que le sujet auquel je répond était la création de tableaux
dynamiques en C++, et du choix entre new ou malloc.
Il est clair qu'en C, le problème ne se pose pas, puisque ni objets ni
new n'existent. Par contre, je ne connais aucun compilateur C++ où ça ne
poserait pas de problème.
La programmation c'est pas un art guidé par des dogmes et des oeillères. Tu
ne peux pas dire c'est comme ça et pas autrement. Il y a tellement de
domaines d'application, de domaines, de contextes particuliers...
Le C++ (le C aussi) sont des langages normés. Même s'il y a toujours des
écarts entre les normes et leurs implémentations, il y a des cas que
l'on retrouve partout.
Ce n'est pas être dogmatique ou avoir des oeillère que de dire que si on
écrit int a=1+1; alors a vaudra 2.
Ce n'est pas plus être dogmatique que de dire que int a=1/0; provoquera
une erreur, et qu'il ne faut pas l'écrire.
Ce n'est pas plus être dogmatique que de dire que dans le cas général
(c'est à dire si C n'est pas un POD),
C* c = (C*) malloc(sizeof(C));
C->toto();
Constituera une erreur de code, et qu'il ne faut pas l'écrire.
Au passage, les compilos font ça souvent hein, regarde les unions en C/C++
:-)
Pas besoin de regarder, c'est tout vu, et ça conforte mon point de vue.
Là aussi, mettre un objet autre qu'un POD dans une union est illégal en
C++.
Si tu alloue un tableau d'octets, puis que tu fais croire à ton compilateur que tu as des objets à l'intérieur en castant, tu as alors un comportement indéfini.
Ben ça dépend de quel compilo tu utilises, de quel genre de code tu écris. Moi, en C ou ASM, il m'arrive souvent de déclarer simplement une zone de mémoire et... de choisir ensuite si c'est des BYTE, WORD, LONG, objets, caractères ou je ne sais quoi. Cela dépend de tellement de choses...
Je rappelle que le sujet auquel je répond était la création de tableaux dynamiques en C++, et du choix entre new ou malloc.
Il est clair qu'en C, le problème ne se pose pas, puisque ni objets ni new n'existent. Par contre, je ne connais aucun compilateur C++ où ça ne poserait pas de problème.
La programmation c'est pas un art guidé par des dogmes et des oeillères. Tu ne peux pas dire c'est comme ça et pas autrement. Il y a tellement de domaines d'application, de domaines, de contextes particuliers...
Le C++ (le C aussi) sont des langages normés. Même s'il y a toujours des écarts entre les normes et leurs implémentations, il y a des cas que l'on retrouve partout.
Ce n'est pas être dogmatique ou avoir des oeillère que de dire que si on écrit int a=1+1; alors a vaudra 2.
Ce n'est pas plus être dogmatique que de dire que int a=1/0; provoquera une erreur, et qu'il ne faut pas l'écrire.
Ce n'est pas plus être dogmatique que de dire que dans le cas général (c'est à dire si C n'est pas un POD),
C* c = (C*) malloc(sizeof(C)); C->toto();
Constituera une erreur de code, et qu'il ne faut pas l'écrire.
Au passage, les compilos font ça souvent hein, regarde les unions en C/C++ :-)
Pas besoin de regarder, c'est tout vu, et ça conforte mon point de vue. Là aussi, mettre un objet autre qu'un POD dans une union est illégal en C++.
-- Loïc
Loïc Joly
AMcD® wrote:
Alexandre wrote:
merci pour le pseudo-programmeur, un jour je te dirais où je travailles.
Ben moi qui suis pourtant réputé pour mon humour spécial et ma grande gueule, je pense qu'il vaut mieux que tu ne le dises pas où tu travailles... Si t'as des gars un peu sérieux et rigoureux au-dessus de toi, quand ils vont lire des morceaux d'anthologie du style :
"Tu vérifies EN PERMANENCE dans ton code le retour de new ? Que c'est lourd !"
Cette phrase est en effet incorrecte. Il aurait fallu dire :
"Il t'arrive de vérifier la valeur de retour de new ? Mais mon pauvre, tu ne connais pas le C++, new ne peut pas retourner autre chose qu'un pointeur valide."
-- Loïc
AMcD® wrote:
Alexandre wrote:
merci pour le pseudo-programmeur, un jour je te dirais où je
travailles.
Ben moi qui suis pourtant réputé pour mon humour spécial et ma grande
gueule, je pense qu'il vaut mieux que tu ne le dises pas où tu travailles...
Si t'as des gars un peu sérieux et rigoureux au-dessus de toi, quand ils
vont lire des morceaux d'anthologie du style :
"Tu vérifies EN PERMANENCE dans ton code le retour de new ? Que c'est lourd
!"
Cette phrase est en effet incorrecte. Il aurait fallu dire :
"Il t'arrive de vérifier la valeur de retour de new ? Mais mon pauvre,
tu ne connais pas le C++, new ne peut pas retourner autre chose qu'un
pointeur valide."
merci pour le pseudo-programmeur, un jour je te dirais où je travailles.
Ben moi qui suis pourtant réputé pour mon humour spécial et ma grande gueule, je pense qu'il vaut mieux que tu ne le dises pas où tu travailles... Si t'as des gars un peu sérieux et rigoureux au-dessus de toi, quand ils vont lire des morceaux d'anthologie du style :
"Tu vérifies EN PERMANENCE dans ton code le retour de new ? Que c'est lourd !"
Cette phrase est en effet incorrecte. Il aurait fallu dire :
"Il t'arrive de vérifier la valeur de retour de new ? Mais mon pauvre, tu ne connais pas le C++, new ne peut pas retourner autre chose qu'un pointeur valide."
-- Loïc
Loïc Joly
AMcD® wrote:
Bien entendu, pour que ça se passe bien, il faut que le reste du programme soit bien écrit pour ne pas causer de problème lors de la remontée de l'exception dans la pile d'appels.
Oui, c'est exactement ce point dont je doute :-)
Ce n'est pas ce que j'avais compris, désolé. En effet, nulle part je n'ai vu mentionnées dnas ce thread les techniques qui permettent de réaliser ça, comme l'encapsulation de ressource selon l'idiome RAII, le fonctionnement à base de transactions,...
-- Loïc
AMcD® wrote:
Bien entendu, pour que ça se passe bien, il faut que le reste
du programme soit bien écrit pour ne pas causer de problème lors de la
remontée de l'exception dans la pile d'appels.
Oui, c'est exactement ce point dont je doute :-)
Ce n'est pas ce que j'avais compris, désolé. En effet, nulle part je
n'ai vu mentionnées dnas ce thread les techniques qui permettent de
réaliser ça, comme l'encapsulation de ressource selon l'idiome RAII, le
fonctionnement à base de transactions,...
Bien entendu, pour que ça se passe bien, il faut que le reste du programme soit bien écrit pour ne pas causer de problème lors de la remontée de l'exception dans la pile d'appels.
Oui, c'est exactement ce point dont je doute :-)
Ce n'est pas ce que j'avais compris, désolé. En effet, nulle part je n'ai vu mentionnées dnas ce thread les techniques qui permettent de réaliser ça, comme l'encapsulation de ressource selon l'idiome RAII, le fonctionnement à base de transactions,...
-- Loïc
AMcD®
Loïc Joly wrote:
Au passage, les compilos font ça souvent hein, regarde les unions en C/C++ :-)
Pas besoin de regarder, c'est tout vu, et ça conforte mon point de vue. Là aussi, mettre un objet autre qu'un POD dans une union est illégal en C++.
Je ne sais pas ce qu'est un POD, par contre, toi, tu devrais me lire plus attentivement. Je disais juste que les unions sont un excellent exemple de cast sauvage "à la volée". Initialement, ça occuppe juste de la mémoire, celle du plus grand type possible déclaré. Ensuite, tu peux en "tirer" divers types de diverses tailles lors de l'exécution.
Eh vi, même en C++ le dogmatisme marche pas.
-- AMcD®
http://arnold.mcdonald.free.fr/
Loïc Joly wrote:
Au passage, les compilos font ça souvent hein, regarde les unions en
C/C++ :-)
Pas besoin de regarder, c'est tout vu, et ça conforte mon point de
vue. Là aussi, mettre un objet autre qu'un POD dans une union est
illégal en C++.
Je ne sais pas ce qu'est un POD, par contre, toi, tu devrais me lire plus
attentivement. Je disais juste que les unions sont un excellent exemple de
cast sauvage "à la volée". Initialement, ça occuppe juste de la mémoire,
celle du plus grand type possible déclaré. Ensuite, tu peux en "tirer"
divers types de diverses tailles lors de l'exécution.
Au passage, les compilos font ça souvent hein, regarde les unions en C/C++ :-)
Pas besoin de regarder, c'est tout vu, et ça conforte mon point de vue. Là aussi, mettre un objet autre qu'un POD dans une union est illégal en C++.
Je ne sais pas ce qu'est un POD, par contre, toi, tu devrais me lire plus attentivement. Je disais juste que les unions sont un excellent exemple de cast sauvage "à la volée". Initialement, ça occuppe juste de la mémoire, celle du plus grand type possible déclaré. Ensuite, tu peux en "tirer" divers types de diverses tailles lors de l'exécution.
Eh vi, même en C++ le dogmatisme marche pas.
-- AMcD®
http://arnold.mcdonald.free.fr/
AMcD®
Loïc Joly wrote:
"Il t'arrive de vérifier la valeur de retour de new ? Mais mon pauvre, tu ne connais pas le C++, new ne peut pas retourner autre chose qu'un pointeur valide."
Mouarf, t'es un grand comique toi.
Doc Visual C++ : "If unsuccessful, by default new returns zero". Si on te permet de redéfinir/ajuster, via _set_new_handler() le comportement de new() lors d'échecs, c'est certainement parce que new retourne toujours des pointeurs valides...
"Il t'arrive de vérifier la valeur de retour de new ? Mais mon pauvre,
tu ne connais pas le C++, new ne peut pas retourner autre chose qu'un
pointeur valide."
Mouarf, t'es un grand comique toi.
Doc Visual C++ : "If unsuccessful, by default new returns zero". Si on te
permet de redéfinir/ajuster, via _set_new_handler() le comportement de new()
lors d'échecs, c'est certainement parce que new retourne toujours des
pointeurs valides...
"Il t'arrive de vérifier la valeur de retour de new ? Mais mon pauvre, tu ne connais pas le C++, new ne peut pas retourner autre chose qu'un pointeur valide."
Mouarf, t'es un grand comique toi.
Doc Visual C++ : "If unsuccessful, by default new returns zero". Si on te permet de redéfinir/ajuster, via _set_new_handler() le comportement de new() lors d'échecs, c'est certainement parce que new retourne toujours des pointeurs valides...
Au passage, les compilos font ça souvent hein, regarde les unions en C/C++ :-)
Pas besoin de regarder, c'est tout vu, et ça conforte mon point de vue. Là aussi, mettre un objet autre qu'un POD dans une union est illégal en C++.
Je ne sais pas ce qu'est un POD, par contre, toi, tu devrais me lire plus attentivement.
Un POD (plain old data) est en gros (voir §9 et §8.5.1 de la norme pour une définition précise) une classe sans constructeur défini par l'utilisateur, sans fonction virtuelle, sans destructeur, sans données privées... et dont les données membre sont des POD. Dit autrement, une structure qu'on pourrait déclarer en C.
Je disais juste que les unions sont un excellent exemple de cast sauvage "à la volée". Initialement, ça occuppe juste de la mémoire, celle du plus grand type possible déclaré. Ensuite, tu peux en "tirer" divers types de diverses tailles lors de l'exécution.
Et je te disais juste que les unions ne permettent *pas* un cast à la volée entre n'importe quoi. Si on a, par exemple :
class A { public: A() : i=0{} private: int i; };
class B { public: ~B() {cout << "Coucou";} }
Alors il est illégal de déclarer une union dont un type soit A ou B. Un bon compilateur fera une erreur à la compilation.
De plus, que ce soit en C ou en C++, un code du type suivant est illégal :
union U { int i; double d; };
U u; u.d=0; int i=u.i;
Peut-être que sur certains compilateurs et avec certains types, ça va donner le résultat auquel tu t'attends (0 ?). Peut-être pas. En tout cas, ces casts sauvages "à la volée" n'ont rien de garanti ni en C, ni en C++.
-- Loïc
AMcD® wrote:
Loïc Joly wrote:
Au passage, les compilos font ça souvent hein, regarde les unions en
C/C++ :-)
Pas besoin de regarder, c'est tout vu, et ça conforte mon point de
vue. Là aussi, mettre un objet autre qu'un POD dans une union est
illégal en C++.
Je ne sais pas ce qu'est un POD, par contre, toi, tu devrais me lire plus
attentivement.
Un POD (plain old data) est en gros (voir §9 et §8.5.1 de la norme pour
une définition précise) une classe sans constructeur défini par
l'utilisateur, sans fonction virtuelle, sans destructeur, sans données
privées... et dont les données membre sont des POD. Dit autrement, une
structure qu'on pourrait déclarer en C.
Je disais juste que les unions sont un excellent exemple de
cast sauvage "à la volée". Initialement, ça occuppe juste de la mémoire,
celle du plus grand type possible déclaré. Ensuite, tu peux en "tirer"
divers types de diverses tailles lors de l'exécution.
Et je te disais juste que les unions ne permettent *pas* un cast à la
volée entre n'importe quoi. Si on a, par exemple :
class A
{
public:
A() : i=0{}
private:
int i;
};
class B
{
public:
~B() {cout << "Coucou";}
}
Alors il est illégal de déclarer une union dont un type soit A ou B. Un
bon compilateur fera une erreur à la compilation.
De plus, que ce soit en C ou en C++, un code du type suivant est illégal :
union U
{
int i;
double d;
};
U u;
u.d=0;
int i=u.i;
Peut-être que sur certains compilateurs et avec certains types, ça va
donner le résultat auquel tu t'attends (0 ?). Peut-être pas. En tout
cas, ces casts sauvages "à la volée" n'ont rien de garanti ni en C, ni
en C++.
Au passage, les compilos font ça souvent hein, regarde les unions en C/C++ :-)
Pas besoin de regarder, c'est tout vu, et ça conforte mon point de vue. Là aussi, mettre un objet autre qu'un POD dans une union est illégal en C++.
Je ne sais pas ce qu'est un POD, par contre, toi, tu devrais me lire plus attentivement.
Un POD (plain old data) est en gros (voir §9 et §8.5.1 de la norme pour une définition précise) une classe sans constructeur défini par l'utilisateur, sans fonction virtuelle, sans destructeur, sans données privées... et dont les données membre sont des POD. Dit autrement, une structure qu'on pourrait déclarer en C.
Je disais juste que les unions sont un excellent exemple de cast sauvage "à la volée". Initialement, ça occuppe juste de la mémoire, celle du plus grand type possible déclaré. Ensuite, tu peux en "tirer" divers types de diverses tailles lors de l'exécution.
Et je te disais juste que les unions ne permettent *pas* un cast à la volée entre n'importe quoi. Si on a, par exemple :
class A { public: A() : i=0{} private: int i; };
class B { public: ~B() {cout << "Coucou";} }
Alors il est illégal de déclarer une union dont un type soit A ou B. Un bon compilateur fera une erreur à la compilation.
De plus, que ce soit en C ou en C++, un code du type suivant est illégal :
union U { int i; double d; };
U u; u.d=0; int i=u.i;
Peut-être que sur certains compilateurs et avec certains types, ça va donner le résultat auquel tu t'attends (0 ?). Peut-être pas. En tout cas, ces casts sauvages "à la volée" n'ont rien de garanti ni en C, ni en C++.
-- Loïc
AMcD®
Loïc Joly wrote:
Peut-être que sur certains compilateurs et avec certains types, ça va donner le résultat auquel tu t'attends (0 ?). Peut-être pas.
Ben j'espère que ça donne pas le bon résultat, vu qu'il faudrait écrire :
i = (int)u.d;
Cela revient à une discussion plus haut. Quand on programme comme une buse, on a des bugs :-).
En tout cas, ces casts sauvages "à la volée" n'ont rien de garanti ni en C, ni en C++.
Certes.
-- AMcD®
http://arnold.mcdonald.free.fr/
Loïc Joly wrote:
Peut-être que sur certains compilateurs et avec certains types, ça va
donner le résultat auquel tu t'attends (0 ?). Peut-être pas.
Ben j'espère que ça donne pas le bon résultat, vu qu'il faudrait écrire :
i = (int)u.d;
Cela revient à une discussion plus haut. Quand on programme comme une buse,
on a des bugs :-).
En tout
cas, ces casts sauvages "à la volée" n'ont rien de garanti ni en C, ni
en C++.
Peut-être que sur certains compilateurs et avec certains types, ça va donner le résultat auquel tu t'attends (0 ?). Peut-être pas.
Ben j'espère que ça donne pas le bon résultat, vu qu'il faudrait écrire :
i = (int)u.d;
Cela revient à une discussion plus haut. Quand on programme comme une buse, on a des bugs :-).
En tout cas, ces casts sauvages "à la volée" n'ont rien de garanti ni en C, ni en C++.
Certes.
-- AMcD®
http://arnold.mcdonald.free.fr/
Loïc Joly
AMcD® wrote:
Loïc Joly wrote:
"Il t'arrive de vérifier la valeur de retour de new ? Mais mon pauvre, tu ne connais pas le C++, new ne peut pas retourner autre chose qu'un pointeur valide."
Mouarf, t'es un grand comique toi.
Non, je suis juste quelqu'un qui connais le C++.
Doc Visual C++ : "If unsuccessful, by default new returns zero". Si on te permet de redéfinir/ajuster, via _set_new_handler() le comportement de new() lors d'échecs, c'est certainement parce que new retourne toujours des pointeurs valides...
Et c'est effectivement un des point sur lequel visual C++, dans ses anciennes versions, n'est pas conforme à la norme C++. Il existe peut-être un flag de compilation qui le rend conforme sur ce point.
Si tu ne jure que par ce que dit Microsoft, voici une autre extrait du MSDN (visiblement d'une version plus récente du compilateur)
In Visual C++ .NET 2002, the new function in the Standard C++ Library will support the behavior specified in the C++ standard, which is to throw a std::bad_alloc exception if the memory allocation fails.
In Visual C++ 2005, the C Runtime Library's new function will also throw a std::bad_alloc exception if the memory allocation fails.
If you still want the non-throwing version of new for the C Runtime Library, link your program with nothrownew.obj. However, when you link with nothrownew.obj, new in the Standard C++ Library will no longer function.
Enfin, voici la définition de new dans le standard : (désolé si c'est un peu long. Tu peux pour gagner du temps ne lire que l'exemple final).
void* operator new(std::size_t size) throw(std::bad_alloc); 1 Effects: The allocation function (3.7.3.1) called by a newexpression (5.3.4) to allocate size bytes of storage suitably aligned to represent any object of that size. 2 Replaceable: a C++ program may define a function with this function signature that displaces the default version defined by the C++ Standard library. 3 Required behavior: Return a nonnull pointer to suitably aligned storage (3.7.3), or else throw a bad_alloc exception. This requirement is binding on a replacement version of this function. 4 Default behavior: — Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to the Standard C library function malloc is unspecified. — Returns a pointer to the allocated storage if the attempt is successful. Otherwise, if the last argument to set_new_handler() was a null pointer, throw bad_alloc. — Otherwise, the function calls the current new_handler (18.4.2.2). If the called function returns, the loop repeats. — The loop terminates when an attempt to allocate the requested storage is successful or when a called new_handler function does not return.
void* operator new(std::size_t size, const std::nothrow_t&) throw(); 5 Effects: Same as above, except that it is called by a placement version of a newexpression when a C++ program prefers a null pointer result as an error indication, instead of a bad_alloc exception. 6 Replaceable: a C++ program may define a function with this function signature that displaces the default version defined by the C++ Standard library. 7 Required behavior: Return a nonnull pointer to suitably aligned storage (3.7.3), or else return a null pointer. This nothrow version of operator new returns a pointer obtained as if acquired from the ordinary version. This requirement is binding on a replacement version of this function. 8 Default behavior: — Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to the Standard C library function malloc is unspecified. — Returns a pointer to the allocated storage if the attempt is successful. Otherwise, if the last argument to set_new_handler() was a null pointer, return a null pointer. — Otherwise, the function calls the current new_handler (18.4.2.2). If the called function returns, the loop repeats. — The loop terminates when an attempt to allocate the requested storage is successful or when a called new_handler function does not return. If the called new_handler function terminates by throwing a bad_alloc exception, the function returns a null pointer.
9 [Example: T* p1 = new T; // throws bad_alloc if it fails T* p2 > new(nothrow) T; // returns 0 if it fails —end example]
-- Loïc
AMcD® wrote:
Loïc Joly wrote:
"Il t'arrive de vérifier la valeur de retour de new ? Mais mon
pauvre, tu ne connais pas le C++, new ne peut pas retourner autre
chose qu'un pointeur valide."
Mouarf, t'es un grand comique toi.
Non, je suis juste quelqu'un qui connais le C++.
Doc Visual C++ : "If unsuccessful, by default new returns zero". Si
on te permet de redéfinir/ajuster, via _set_new_handler() le
comportement de new() lors d'échecs, c'est certainement parce que new
retourne toujours des pointeurs valides...
Et c'est effectivement un des point sur lequel visual C++, dans ses
anciennes versions, n'est pas conforme à la norme C++. Il existe
peut-être un flag de compilation qui le rend conforme sur ce point.
Si tu ne jure que par ce que dit Microsoft, voici une autre extrait du
MSDN (visiblement d'une version plus récente du compilateur)
In Visual C++ .NET 2002, the new function in the Standard C++ Library
will support the behavior specified in the C++ standard, which is to
throw a std::bad_alloc exception if the memory allocation fails.
In Visual C++ 2005, the C Runtime Library's new function will also
throw a std::bad_alloc exception if the memory allocation fails.
If you still want the non-throwing version of new for the C Runtime
Library, link your program with nothrownew.obj. However, when you
link with nothrownew.obj, new in the Standard C++ Library will no
longer function.
Enfin, voici la définition de new dans le standard : (désolé si c'est un
peu long. Tu peux pour gagner du temps ne lire que l'exemple final).
void* operator new(std::size_t size) throw(std::bad_alloc); 1
Effects: The allocation function (3.7.3.1) called by a newexpression
(5.3.4) to allocate size bytes of storage suitably aligned to
represent any object of that size. 2 Replaceable: a C++ program may
define a function with this function signature that displaces the
default version defined by the C++ Standard library. 3 Required
behavior: Return a nonnull pointer to suitably aligned storage
(3.7.3), or else throw a bad_alloc exception. This requirement is
binding on a replacement version of this function. 4 Default
behavior: — Executes a loop: Within the loop, the function first
attempts to allocate the requested storage. Whether the attempt
involves a call to the Standard C library function malloc is
unspecified. — Returns a pointer to the allocated storage if the
attempt is successful. Otherwise, if the last argument to
set_new_handler() was a null pointer, throw bad_alloc. — Otherwise,
the function calls the current new_handler (18.4.2.2). If the called
function returns, the loop repeats. — The loop terminates when an
attempt to allocate the requested storage is successful or when a
called new_handler function does not return.
void* operator new(std::size_t size, const std::nothrow_t&) throw();
5 Effects: Same as above, except that it is called by a placement
version of a newexpression when a C++ program prefers a null pointer
result as an error indication, instead of a bad_alloc exception. 6
Replaceable: a C++ program may define a function with this function
signature that displaces the default version defined by the C++
Standard library. 7 Required behavior: Return a nonnull pointer to
suitably aligned storage (3.7.3), or else return a null pointer. This
nothrow version of operator new returns a pointer obtained as if
acquired from the ordinary version. This requirement is binding on a
replacement version of this function. 8 Default behavior: — Executes
a loop: Within the loop, the function first attempts to allocate the
requested storage. Whether the attempt involves a call to the
Standard C library function malloc is unspecified. — Returns a
pointer to the allocated storage if the attempt is successful.
Otherwise, if the last argument to set_new_handler() was a null
pointer, return a null pointer. — Otherwise, the function calls the
current new_handler (18.4.2.2). If the called function returns, the
loop repeats. — The loop terminates when an attempt to allocate the
requested storage is successful or when a called new_handler function
does not return. If the called new_handler function terminates by
throwing a bad_alloc exception, the function returns a null pointer.
9 [Example: T* p1 = new T; // throws bad_alloc if it fails T* p2 > new(nothrow) T; // returns 0 if it fails —end example]
"Il t'arrive de vérifier la valeur de retour de new ? Mais mon pauvre, tu ne connais pas le C++, new ne peut pas retourner autre chose qu'un pointeur valide."
Mouarf, t'es un grand comique toi.
Non, je suis juste quelqu'un qui connais le C++.
Doc Visual C++ : "If unsuccessful, by default new returns zero". Si on te permet de redéfinir/ajuster, via _set_new_handler() le comportement de new() lors d'échecs, c'est certainement parce que new retourne toujours des pointeurs valides...
Et c'est effectivement un des point sur lequel visual C++, dans ses anciennes versions, n'est pas conforme à la norme C++. Il existe peut-être un flag de compilation qui le rend conforme sur ce point.
Si tu ne jure que par ce que dit Microsoft, voici une autre extrait du MSDN (visiblement d'une version plus récente du compilateur)
In Visual C++ .NET 2002, the new function in the Standard C++ Library will support the behavior specified in the C++ standard, which is to throw a std::bad_alloc exception if the memory allocation fails.
In Visual C++ 2005, the C Runtime Library's new function will also throw a std::bad_alloc exception if the memory allocation fails.
If you still want the non-throwing version of new for the C Runtime Library, link your program with nothrownew.obj. However, when you link with nothrownew.obj, new in the Standard C++ Library will no longer function.
Enfin, voici la définition de new dans le standard : (désolé si c'est un peu long. Tu peux pour gagner du temps ne lire que l'exemple final).
void* operator new(std::size_t size) throw(std::bad_alloc); 1 Effects: The allocation function (3.7.3.1) called by a newexpression (5.3.4) to allocate size bytes of storage suitably aligned to represent any object of that size. 2 Replaceable: a C++ program may define a function with this function signature that displaces the default version defined by the C++ Standard library. 3 Required behavior: Return a nonnull pointer to suitably aligned storage (3.7.3), or else throw a bad_alloc exception. This requirement is binding on a replacement version of this function. 4 Default behavior: — Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to the Standard C library function malloc is unspecified. — Returns a pointer to the allocated storage if the attempt is successful. Otherwise, if the last argument to set_new_handler() was a null pointer, throw bad_alloc. — Otherwise, the function calls the current new_handler (18.4.2.2). If the called function returns, the loop repeats. — The loop terminates when an attempt to allocate the requested storage is successful or when a called new_handler function does not return.
void* operator new(std::size_t size, const std::nothrow_t&) throw(); 5 Effects: Same as above, except that it is called by a placement version of a newexpression when a C++ program prefers a null pointer result as an error indication, instead of a bad_alloc exception. 6 Replaceable: a C++ program may define a function with this function signature that displaces the default version defined by the C++ Standard library. 7 Required behavior: Return a nonnull pointer to suitably aligned storage (3.7.3), or else return a null pointer. This nothrow version of operator new returns a pointer obtained as if acquired from the ordinary version. This requirement is binding on a replacement version of this function. 8 Default behavior: — Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to the Standard C library function malloc is unspecified. — Returns a pointer to the allocated storage if the attempt is successful. Otherwise, if the last argument to set_new_handler() was a null pointer, return a null pointer. — Otherwise, the function calls the current new_handler (18.4.2.2). If the called function returns, the loop repeats. — The loop terminates when an attempt to allocate the requested storage is successful or when a called new_handler function does not return. If the called new_handler function terminates by throwing a bad_alloc exception, the function returns a null pointer.
9 [Example: T* p1 = new T; // throws bad_alloc if it fails T* p2 > new(nothrow) T; // returns 0 if it fails —end example]