Dans cette question , quelqu'un a suggéré dans un commentaire que je devrais pas transforme le résultat de malloc
, c'est-à-dire.
int *sieve = malloc(sizeof(int) * length);
plutôt que:
int *sieve = (int *) malloc(sizeof(int) * length);
Pourquoi serait-ce le cas?
Non; vous ne lancez pas le résultat , car:
void *
est automatiquement et sûrement promu en un autre type de pointeur dans ce cas.<stdlib.h>
. Cela peut provoquer des plantages (ou, pire, et non causer un plantage jusqu’à plus tard, dans une partie totalement différente du code). Considérez ce qui se passe si les pointeurs et les entiers sont de tailles différentes. alors vous cachez un avertissement en diffusant et vous risquez de perdre une partie de votre adresse renvoyée. Remarque: à partir de C11, les fonctions implicites sont passées de C et ce point n'est plus pertinent puisqu'il n'existe aucune hypothèse automatique selon laquelle les fonctions non déclarées renvoient int
.Pour clarifier, notez que j'ai dit "vous ne lancez pas", pas "vous n'avez pas besoin de pour lancer". À mon avis, c'est un échec pour inclure le casting, même si vous avez bien compris. Cela ne présente tout simplement aucun avantage, mais un ensemble de risques potentiels, et l'inclusion de la distribution indique que vous ne connaissez pas les risques.
Notez également, comme le soulignent les commentateurs, que ce qui précède parle de C pur, pas de C++. Je crois fermement en C et C++ en tant que langages séparés.
Pour ajouter plus, votre code répète inutilement les informations de type (int
) qui peuvent provoquer des erreurs. Il est préférable de déréférencer le pointeur utilisé pour stocker la valeur de retour afin de "verrouiller" les deux ensembles:
int *sieve = malloc(length * sizeof *sieve);
Cela déplace également le length
vers l'avant pour une visibilité accrue et supprime les parenthèses redondantes avec sizeof
; ils ne sont nécessaires que lorsque l'argument est un nom de type. Beaucoup de gens semblent ne pas savoir (ou ignorer) cela, ce qui rend leur code plus verbeux. Rappelez-vous: sizeof
n'est pas une fonction! :)
Tout en déplaçant length
vers l'avant peut augmenter la visibilité dans certains cas rares, il convient également de noter que, dans le cas général, il convient de: mieux écrire l'expression comme:
int *sieve = malloc(sizeof *sieve * length);
Puisque garder la sizeof
en premier, dans ce cas, assure que la multiplication est faite avec au moins size_t
math.
Comparez: malloc(sizeof *sieve * length * width)
vs. malloc(length * width * sizeof *sieve)
la seconde peut dépasser le length * width
lorsque width
et length
sont des types plus petits que size_t
.
En C, vous n'avez pas besoin de convertir la valeur de retour de malloc
. Le pointeur sur void renvoyé par malloc
est automatiquement converti dans le type correct. Toutefois, si vous souhaitez que votre code soit compilé avec un compilateur C++, une conversion est nécessaire. Une alternative préférée parmi la communauté est d'utiliser les éléments suivants:
int *sieve = malloc(sizeof *sieve * length);
ce qui vous évite en outre de vous inquiéter de changer le côté droit de l'expression si vous changez le type de sieve
.
Les lancers sont mauvais, comme les gens l'ont souligné. Spécialement lance des pointeurs.
Vous faites vous lancez, car:
type *
par rapport à type **
.#include
un fichier d'en-tête approprié manque à la forêt d'arbres . C’est la même chose que de dire "ne vous inquiétez pas du fait que vous n’avez pas demandé au compilateur de se plaindre de ne pas voir les prototypes - ce satané stdlib.h est la VRAIE chose importante à retenir!"malloc()
sont détectés beaucoup plus rapidement lorsqu'il y a un casting. Comme pour les assertions, les annotations qui révèlent une intention réduisent les bogues.Comme indiqué par d’autres, il n’est pas nécessaire pour C, mais pour C++. Si vous pensez compiler votre code C avec un compilateur C++, pour quelle raison que ce soit, vous pouvez utiliser une macro à la place, par exemple:
#ifdef __cplusplus
# define NEW(type, count) ((type *)calloc(count, sizeof(type)))
#else
# define NEW(type, count) (calloc(count, sizeof(type)))
#endif
De cette façon, vous pouvez toujours l'écrire de manière très compacte:
int *sieve = NEW(int, 1);
et il compilera pour C et C++.
De la Wikipedia :
Avantages de la coulée
L'inclusion de la conversion peut permettre à un programme ou une fonction C de compiler en C++.
La distribution autorise les versions antérieures à 1989 de malloc ayant à l'origine renvoyé un caractère *.
Casting peut aider le développeur à identifier les incohérences dans le dimensionnement des types si le type de pointeur de destination change, en particulier si le pointeur est déclaré loin de l'appel malloc () (bien que les compilateurs modernes et les analyseurs statiques puissent avertir de ce comportement sans requérir le transfert).
Inconvénients du casting
Selon la norme ANSI C, la distribution est redondante.
L'ajout de la distribution peut masquer l'échec d'inclure l'en-tête stdlib.h , dans lequel se trouve le prototype de malloc. En l’absence de prototype pour malloc, la norme exige que le compilateur C suppose que malloc renvoie un int. S'il n'y a pas de transtypage, un avertissement est émis lorsque cet entier est affecté au pointeur. Cependant, avec le casting, cet avertissement n'est pas produit, masquant un bogue. Sur certaines architectures et certains modèles de données (tels que LP64 sur les systèmes 64 bits, où longs et les pointeurs sont 64 bits et int est 32 bits), cette erreur peut entraîner un comportement indéfini, car le malloc déclaré implicitement renvoie un message 32- valeur de bit alors que la fonction réellement définie renvoie une valeur de 64 bits. Selon les conventions d’appel et la structure de la mémoire, cela peut entraîner le bris de la pile. Ce problème est moins susceptible de passer inaperçu dans les compilateurs modernes, car ils produisent uniformément des avertissements indiquant qu'une fonction non déclarée a été utilisée. Par conséquent, un avertissement apparaîtra. Par exemple, le comportement par défaut de GCC consiste à afficher un avertissement indiquant "déclaration implicite incompatible de la fonction intégrée", que la conversion soit présente ou non.
Si le type du pointeur est modifié lors de sa déclaration, il peut également être nécessaire de modifier toutes les lignes où malloc est appelé et converti.
Bien que malloc sans casting soit la méthode préférée et que la plupart des programmeurs expérimentés le choisissent , vous devez utiliser celui qui vous convient le mieux.
i.e: Si vous avez besoin de compiler le programme C en C++ (bien que ce soit un langage séparé), vous devez utiliser malloc
avec la transtypage.
En C, vous pouvez implicitement convertir un pointeur vide en un autre type de pointeur, ainsi un transtypage n'est pas nécessaire. En utiliser un peut suggérer à l'observateur occasionnel qu'il y a une raison pour laquelle on en a besoin, ce qui peut être trompeur.
Vous ne transmettez pas le résultat de malloc, car cela ajoute un fouillis inutile à votre code.
La raison la plus courante pour laquelle les utilisateurs affichent le résultat de malloc est qu'ils ne savent pas comment fonctionne le langage C. C'est un signe d'avertissement: si vous ne savez pas comment fonctionne un mécanisme de langage particulier, alors ne le faites pas . Cherchez ou demandez sur Stack Overflow.
Certains commentaires:
Un pointeur vide peut être converti vers/à partir de tout autre type de pointeur sans conversion explicite (C11 6.3.2.3 et 6.5.16.1).
C++ n'autorisera toutefois pas une conversion implicite entre void*
et un autre type de pointeur. Donc, en C++, le casting aurait été correct. Mais si vous programmez en C++, vous devez utiliser new
et non malloc (). Et vous ne devriez jamais compiler du code C en utilisant un compilateur C++.
Si vous devez prendre en charge C et C++ avec le même code source, utilisez les commutateurs de compilateur pour marquer les différences. N'essayez pas de placer les deux normes linguistiques avec le même code, car elles ne sont pas compatibles.
Si un compilateur C ne peut pas trouver une fonction parce que vous avez oublié d'inclure l'en-tête, vous obtiendrez une erreur du compilateur/éditeur de liens à ce sujet. Donc, si vous avez oublié d'inclure <stdlib.h>
ce n'est pas grave, vous ne pourrez pas créer votre programme.
Sur les anciens compilateurs qui suivent une version de la norme datant de plus de 25 ans, oublier d'inclure <stdlib.h>
entraînerait un comportement dangereux. Parce que dans cet ancien standard, les fonctions sans prototype visible convertissaient implicitement le type de retour en int
. Lancer explicitement le résultat de malloc cacherait alors ce bogue.
Mais ce n'est vraiment pas un problème. Vous n'utilisez pas un ordinateur de 25 ans, alors pourquoi voudriez-vous utiliser un compilateur de 25 ans?
En C, vous obtenez une conversion implicite de void*
vers un autre pointeur (de données).
La conversion de la valeur renvoyée par malloc()
n'est pas nécessaire à présent, mais j'aimerais ajouter un point qui semble ne pas avoir été signalé:
Dans les temps anciens, c’est-à-dire qu'avant , ANSI C fournit le void *
en tant que type générique de pointeurs, char *
est le tapez pour un tel usage. Dans ce cas, la distribution peut arrêter les avertissements du compilateur.
Référence: C FAQ
Il n'est pas obligatoire de convertir les résultats de malloc
, car il renvoie void*
, et un void*
peut être pointé sur n'importe quel type de données.
En ajoutant simplement mon expérience, en étudiant en ingénierie informatique, je constate que les deux ou trois professeurs que j’ai vu écrire en C ont toujours jeté Malloc, mais celui que j’ai demandé (avec un immense CV et une compréhension de C) m’a dit que c’était absolument inutile, mais utilisé pour être absolument spécifique, et pour amener les étudiants dans la mentalité d’être absolument spécifique. Essentiellement, le casting ne changera rien à son fonctionnement, il fera exactement ce qu'il dit, allouera de la mémoire, et le casting ne le produira pas, vous obtiendrez la même mémoire, et même si vous le convertissez en un autre par erreur (et en évitant le compilateur) erreurs) C y accédera de la même manière.
Edit: Casting a un certain point. Lorsque vous utilisez la notation de tableau, le code généré doit savoir combien de places de mémoire il doit avancer pour atteindre le début de l’élément suivant, ceci est obtenu par transtypage. De cette façon, vous savez que pour un double, vous avez 8 octets de plus, tandis que pour un int, vous avez 4, et ainsi de suite. Ainsi, cela n'a aucun effet si vous utilisez la notation par pointeur, cela devient nécessaire en notation tableau.
Voici ce que Le manuel GNU C Référence de la bibliothèque C dit:
Vous pouvez stocker le résultat de
malloc
dans toute variable de pointeur sans transtypage, car ISO C convertit automatiquement le typevoid *
en un autre type de pointeur, si nécessaire. Mais le transtypage est nécessaire dans des contextes autres que les opérateurs d'affectation ou si vous souhaitez que votre code soit exécuté en C traditionnel.
Et en effet, le norme ISO C11 (p347) le dit:
Le pointeur renvoyé si l'allocation réussit est correctement aligné de sorte qu'il puisse être affecté à un pointeur sur tout type d'objet nécessitant un alignement fondamental, puis utilisé pour accéder à un tel objet ou à un tableau d'objets de ce type dans l'espace alloué (jusqu'au l'espace est explicitement désalloué)
Un pointeur vide est un pointeur générique et C prend en charge la conversion implicite d'un type de pointeur vide à d'autres types. Il n'est donc pas nécessaire de le transtyper explicitement.
Toutefois, si vous souhaitez que le même code fonctionne parfaitement sur une plate-forme C++, qui ne prend pas en charge la conversion implicite, vous devez procéder à la conversion de type. Tout dépend donc de la convivialité.
Le type renvoyé est void *, qui peut être converti dans le type de pointeur de données souhaité pour pouvoir être déréférencé.
En langage C, un pointeur vide peut être affecté à n’importe quel pointeur. Par conséquent, vous ne devez pas utiliser de transtypage. Si vous voulez une allocation "type safe", je peux vous recommander les fonctions de macro suivantes, que j'utilise toujours dans mes projets C:
#include <stdlib.h>
#define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
#define NEW(ptr) NEW_ARRAY((ptr), 1)
Avec ceux-ci en place, vous pouvez simplement dire
NEW_ARRAY(sieve, length);
Pour les tableaux non dynamiques, la troisième macro fonction indispensable est
#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
ce qui rend les boucles de matrice plus sûres et plus pratiques:
int i, a[100];
for (i = 0; i < LEN(a); i++) {
...
}
Cela dépend du langage de programmation et du compilateur. Si vous utilisez malloc
en C, il n'est pas nécessaire de la transtyper, car elle sera automatiquement transtypée. Toutefois, si vous utilisez C++, vous devez taper cast car malloc
renverra un void*
type.
Les gens habitués à GCC et Clang sont gâtés. Ce n'est pas si bon que ça.
Au fil des ans, j'ai été assez horrifié par les compilateurs incroyablement âgés que je devais utiliser. Souvent, les entreprises et les gestionnaires adoptent une approche ultra-conservatrice pour changer de compilateur et ne vont même pas tester si un nouveau compilateur (avec une meilleure conformité aux normes et optimisation du code) fonctionnera dans leur système. La réalité pratique pour les développeurs qui travaillent est que lorsque vous codez, vous devez couvrir vos bases et, malheureusement, lancer des mallocs est une bonne habitude si vous ne pouvez pas contrôler quel compilateur peut être appliqué à votre code.
Je suggérerais également que de nombreuses organisations appliquent leur propre norme de codage et que that devrait être la méthode que les gens suivent si elle est définie. En l'absence de directives explicites, j'ai tendance à privilégier les compilations les plus susceptibles d'être compilées partout, plutôt que l'adhésion scrupuleuse à une norme.
L'argument selon lequel ce n'est pas nécessaire selon les normes actuelles est tout à fait valable. Mais cet argument omet les aspects pratiques du monde réel. Nous ne codons pas dans un monde régi exclusivement par le niveau actuel, mais par les aspects pratiques de ce que j'aime appeler "le champ de réalité du management local". Et c'est plus tordu que l'espace-temps n'a jamais été. :-)
YMMV.
J'ai tendance à penser que le casting de malloc est une opération défensive. Pas joli, pas parfait, mais généralement sans danger. (Honnêtement, si vous n’avez pas inclus stdlib.h, alors vous avez chemin plus de problèmes que le casting de malloc!).
Je mets dans le casting simplement pour montrer la désapprobation du vilain trou dans le système de types, ce qui permet à un code tel que l'extrait suivant de se compiler sans diagnostics, même si aucun cast n'est utilisé pour provoquer la mauvaise conversion:
double d;
void *p = &d;
int *q = p;
Je souhaite que cela n'existait pas (et ce n'est pas le cas en C++) et je lance donc. Cela représente mon goût et ma politique de programmation. Je ne lance pas seulement un pointeur, mais effectivement, je vote, et chassant les démons stupides . Si je ne peux pas réellement jeter la stupidité , laissez-moi au moins exprimer le souhait de le faire avec un geste de manifestation.
En fait, une bonne pratique consiste à envelopper malloc
(et ses amis) avec des fonctions renvoyant unsigned char *
, et à ne jamais utiliser void *
dans votre code. Si vous avez besoin d'un pointeur générique vers n'importe quel objet, utilisez un char *
ou unsigned char *
, et effectuez des conversions dans les deux sens. La seule détente à laquelle vous pouvez vous adonner consiste peut-être à utiliser des fonctions telles que memset
et memcpy
sans transtypage.
En ce qui concerne le casting et la compatibilité C++, si vous écrivez votre code de telle sorte qu'il soit compilé en C et C++ (dans ce cas, vous devez convertir le renvoyer la valeur malloc
lorsque vous l'assignez à autre chose que void *
), vous pouvez effectuer une opération très utile pour vous-même: vous pouvez utiliser des macros pour la conversion qui se traduisent par des conversions de style C++ lors de la compilation en C++, mais réduire à un cast C lors de la compilation en C:
/* In a header somewhere */
#ifdef __cplusplus
#define strip_qual(TYPE, EXPR) (const_cast<TYPE>(EXPR))
#define convert(TYPE, EXPR) (static_cast<TYPE>(EXPR))
#define coerce(TYPE, EXPR) (reinterpret_cast<TYPE>(EXPR))
#else
#define strip_qual(TYPE, EXPR) ((TYPE) (EXPR))
#define convert(TYPE, EXPR) ((TYPE) (EXPR))
#define coerce(TYPE, EXPR) ((TYPE) (EXPR))
#endif
Si vous vous en tenez à ces macros, une simple recherche grep
de votre base de code pour trouver ces identificateurs vous indiquera où se trouvent tous vos conversions. Vous pourrez ainsi vérifier si certains d'entre eux sont incorrects.
Ensuite, à l'avenir, si vous compilez régulièrement le code avec C++, il imposera l'utilisation d'un transtypage approprié. Par exemple, si vous utilisez strip_qual
simplement pour supprimer un const
ou volatile
, mais que le programme change de sorte qu'une conversion de type est maintenant impliquée, vous obtiendrez un diagnostic et vous devrez utiliser une combinaison de moulages pour obtenir la conversion souhaitée.
Pour vous aider à adhérer à ces macros, le compilateur GNU C++ (pas C!) A une belle fonctionnalité: un diagnostic facultatif produit pour toutes les occurrences de transtypages de style C.
-Wold-style-cast (C++ et Objective-C++ uniquement) Avertir si un casting de style ancien (style C) vers un type non vide est utilisé Dans les conditions suivantes: un programme C++. Les conversions de style nouveau (dynamic_cast, Static_cast, reinterpret_cast et const_cast) sont moins vulnérables Aux effets inattendus et beaucoup plus faciles à rechercher.
Si votre code C est compilé en C++, vous pouvez utiliser cette option -Wold-style-cast
pour connaître toutes les occurrences de la syntaxe de conversion (type)
susceptible de s’insérer dans le code, et effectuer un suivi de ces diagnostics en les remplaçant par un choix approprié parmi les macros ci-dessus (ou une combinaison, si nécessaire).
Ce traitement des conversions est la plus grande justification technique autonome permettant de travailler dans un "Clean C": les dialectes combinés C et C++, ce qui justifie techniquement la conversion de la valeur de retour de malloc
.
Je préfère faire le casting, mais pas manuellement. Mon favori utilise les macros g_new
et g_new0
de Glib. Si glib n'est pas utilisé, j'ajouterais des macros similaires. Ces macros réduisent la duplication de code sans compromettre la sécurité du type. Si vous vous trompez de type, vous obtenez une conversion implicite entre des pointeurs non vides, ce qui provoque un avertissement (erreur en C++). Si vous oubliez d'inclure l'en-tête qui définit g_new
et g_new0
, vous obtiendrez une erreur. g_new
et g_new0
prennent tous deux les mêmes arguments, contrairement à malloc
qui prend moins d'arguments que calloc
. Ajoutez simplement 0
pour obtenir une mémoire initialisée à zéro. Le code peut être compilé avec un compilateur C++ sans modifications.
malloc()
.En général, vous ne lancez pas vers ou depuis void *
.
Une raison typique invoquée pour ne pas le faire est que l'échec de #include <stdlib.h>
pourrait passer inaperçu. Cela n’est plus un problème depuis longtemps puisque C99 a rendu des déclarations de fonctions implicites illégales, donc si votre compilateur est conforme à au moins C99, vous recevoir un message de diagnostic.
Mais il y a une raison beaucoup plus forte pour ne pas introduire de fontes de pointeur inutiles:
En C, un la conversion du pointeur est presque toujours une erreur. Cela est dû à la règle suivante (§6.5 p7 dans N1570, dernier projet pour C11):
La valeur stockée d'un objet doit être accessible uniquement par une expression lvalue qui possède l'un des types suivants:
- un type compatible avec le type effectif de l'objet,
- une version qualifiée d'un type compatible avec le type effectif de l'objet,
- un type qui est le type signé ou non signé correspondant au type effectif de l'objet,
- un type qui est le type signé ou non signé correspondant à une version qualifiée du type effectif de l'objet,
- un type d'agrégat ou d'union qui inclut l'un des types susmentionnés parmi ses membres (y compris, de manière récursive, un membre d'un syndicat sous-agrégé ou confiné), ou
- un type de caractère.
Cette règle est également appelée règle de crénelage strict . Le code suivant est donc un comportement non défini :
long x = 5;
double *p = (double *)&x;
double y = *p;
Et, ce qui est parfois surprenant, voici ce qui suit:
struct foo { int x; };
struct bar { int x; int y; };
struct bar b = { 1, 2};
struct foo *p = (struct foo *)&b;
int z = p->x;
Parfois, vous do avez besoin de lancer des pointeurs, mais étant donné la règle de crénelage stricte , vous devez faire très attention à cela. Ainsi, toute occurrence d’un pointeur dans votre code est un endroit où vous vous devez vérifier sa validité. Par conséquent, vous n'écrivez jamais une distribution de pointeur inutile.
En un mot: Parce qu'en C, toute l'occurrence d'un pointeur converti devrait déclencher un drapeau rouge pour le code requérant une attention particulière, vous ne devriez jamais écrire inutile le pointeur est projeté.
Notes de côté:
Il existe des cas où vous avez réellement besoin d'une conversion vers void *
, par exemple. si vous voulez imprimer un pointeur:
int x = 5;
printf("%p\n", (void *)&x);
La conversion est nécessaire ici, car printf()
est une fonction variadique, les conversions implicites ne fonctionnent donc pas.
En C++, la situation est différente. La diffusion de types de pointeurs est quelque peu commune (et correcte) lorsqu'il s'agit d'objets de classes dérivées. Par conséquent, il est logique qu'en C++, la conversion vers et depuis void *
soit non implicite. C++ a tout un ensemble de différentes saveurs de casting.
La meilleure chose à faire lors de la programmation en C chaque fois que cela est possible:
-Wall
et corrigez toutes les erreurs et tous les avertissementsauto
-Wall
et -std=c++11
. Corrigez toutes les erreurs et tous les avertissements.Cette procédure vous permet de tirer parti de la vérification de type stricte C++, réduisant ainsi le nombre de bogues. En particulier, cette procédure vous oblige à inclure stdlib.h
ou vous obtiendrez
malloc
n'a pas été déclaré dans cette étendue
et vous oblige également à jeter le résultat de malloc
ou vous obtiendrez
conversion invalide de
void*
àT*
ou quel que soit votre type de cible.
Les seuls avantages de l'écriture en C au lieu de C++ que je peux trouver sont
Notez que le second inconvénient devrait dans l'idéal disparaître lors de l'utilisation du sous-ensemble commun à C avec la fonctionnalité polymorphe statique.
Pour ceux qui trouvent les règles strictes C++ peu pratiques, nous pouvons utiliser la fonctionnalité C++ 11 avec le type inféré
auto memblock=static_cast<T*>(malloc(n*sizeof(T))); //Mult may overflow...
Le casting ne concerne que le C++ et non le C. Si vous utilisez un compilateur C++, il vaut mieux le changer en compilateur C.
Le concept derrière le pointeur vide est qu'il peut être converti en n'importe quel type de données, raison pour laquelle malloc renvoie vide. Aussi, vous devez être conscient de la conversion automatique. Il n’est donc pas obligatoire de lancer le pointeur mais vous devez le faire. Cela aide à garder le code propre et au débogage
Un pointeur vide est un pointeur générique et C prend en charge la conversion implicite d'un type de pointeur vide à d'autres types. Il n'est donc pas nécessaire de le transtyper explicitement.
Toutefois, si vous souhaitez que le même code fonctionne parfaitement sur une plate-forme C++, qui ne prend pas en charge la conversion implicite, vous devez procéder à la conversion de type. Tout dépend donc de la convivialité.
Comme indiqué par d’autres, il n’est pas nécessaire pour C, mais pour C++.
L'inclusion de la conversion peut permettre à un programme ou une fonction C de compiler en C++.
En C, cela n’est pas nécessaire, car void * est automatiquement et sûrement promu en un autre type de pointeur.
Mais si vous lancez alors, cela peut cacher une erreur si vous avez oublié d'inclure stdlib.h. Cela peut provoquer des plantages (ou, pire, ne pas provoquer de crash avant bien plus tard dans une partie totalement différente du code).
Parce que stdlib.h contient le prototype pour malloc est trouvé. En l’absence de prototype pour malloc, la norme exige que le compilateur C suppose que malloc renvoie un int. S'il n'y a pas de transtypage, un avertissement est émis lorsque cet entier est affecté au pointeur. Cependant, avec le casting, cet avertissement n'est pas produit, masquant un bogue.
Le casting de malloc est inutile en C mais obligatoire en C++.
Le casting est inutile en C à cause de:
void *
est automatiquement et en toute sécurité promu en tout autre type de pointeur dans le cas de C.<stdlib.h>
. Cela peut provoquer des accidents.malloc
est appelé et converti.D'autre part, la diffusion peut augmenter la portabilité de votre programme. c'est-à-dire qu'il permet à un programme ou une fonction C de compiler en C++.