Pregunta

En esta pregunta, sugirió alguien en un comentario Eso deberia no emitir el resultado de malloc, es decir.

int *sieve = malloc(sizeof(int) * length);

en vez de:

int *sieve = (int *) malloc(sizeof(int) * length);

Por qué sería este el caso?

¿Fue útil?

Solución

No;tú no emitir el resultado, ya que:

  • Es innecesario, como void * en este caso se promueve de forma automática y segura a cualquier otro tipo de puntero.
  • Agrega desorden al código, las conversiones no son muy fáciles de leer (especialmente si el tipo de puntero es largo).
  • Te hace repetirte lo que generalmente es malo.
  • Puede ocultar un error si olvidó incluirlo <stdlib.h>.Esto puede provocar accidentes (o, peor aún, no causar un bloqueo hasta mucho más tarde en alguna parte totalmente diferente del código).Considere lo que sucede si los punteros y los números enteros tienen tamaños diferentes;entonces estás ocultando una advertencia al transmitir y podrías perder partes de tu dirección de retorno.Nota:a partir de C11, las funciones implícitas han desaparecido de C, y este punto ya no es relevante ya que no se supone automáticamente que las funciones no declaradas regresen int.

Como aclaración, tenga en cuenta que dije "no lanzas", no "no lanzas". necesidad lanzar".En mi opinión, es un fracaso incluir el elenco, incluso si lo hiciste bien.Simplemente no hay beneficios al hacerlo, pero sí muchos riesgos potenciales, e incluir el yeso indica que no conoces los riesgos.

También tenga en cuenta, como señalan los comentaristas, que lo anterior habla de C puro, no de C++.Creo firmemente en C y C++ como lenguajes separados.

Para agregar más, su código repite innecesariamente la información de tipo (int) lo que puede provocar errores.Es mejor eliminar la referencia al puntero que se utiliza para almacenar el valor de retorno, para "bloquear" los dos juntos:

int *sieve = malloc(length * sizeof *sieve);

Esto también mueve el length al frente para mayor visibilidad y elimina los paréntesis redundantes con sizeof;ellos solo son necesarios cuando el argumento es un nombre de tipo.Mucha gente parece no saber (o ignorar) esto, lo que hace que su código sea más detallado.Recordar: sizeof ¡No es una función!:)


mientras se mueve length al frente puede Para aumentar la visibilidad en algunos casos raros, también se debe prestar atención a que, en el caso general, debería ser mejor escribir la expresión como:

int *sieve = malloc(sizeof *sieve * length);

Desde que mantuvo el sizeof primero, en este caso, garantiza que la multiplicación se realice con al menos size_t matemáticas.

Comparar: malloc(sizeof *sieve * length * width) vs. malloc(length * width * sizeof *sieve) el segundo puede desbordar el length * width cuando width y length son tipos más pequeños que size_t.

Otros consejos

En C, no necesita emitir el valor de retorno de malloc. El puntero a vacío devuelto por sieve se convierte automáticamente al tipo correcto. Sin embargo, si desea que su código se compile con un compilador de C ++, se necesita un reparto. Una alternativa preferida entre la comunidad es usar lo siguiente:

int *sieve = malloc(sizeof *sieve * length);

que además te libera de tener que preocuparte por cambiar el lado derecho de la expresión si alguna vez cambias el tipo de <=>.

Los moldes son malos, como la gente ha señalado. Especialmente moldes de puntero.

Usted hace elenco, porque:

  • Hace que su código sea más portátil entre C y C ++, y como lo demuestra la experiencia de SO, muchos programadores afirman que están escribiendo en C cuando realmente están escribiendo en C ++ (o compilador local C plus) extensiones).
  • De lo contrario, puede ocultar un error : tenga en cuenta todos los ejemplos SO de confusión cuando se escribe type * versus type **.
  • La idea de que le impide darse cuenta de que no pudo #include un archivo de encabezado apropiado pierde el bosque para los árboles . Es lo mismo que decir & "; ¡No te preocupes por el hecho de que no pudiste pedirle al compilador que se quejara por no ver prototipos - ese molesto stdlib.h es lo REAL realmente importante para recordar! &";
  • Fuerza una verificación cognitiva adicional . Pone el tipo (presunto) deseado justo al lado de la aritmética que está haciendo para el tamaño bruto de esa variable. Apuesto a que podrías hacer un estudio SO que muestre que malloc() los errores se detectan mucho más rápido cuando hay un elenco. Al igual que con las afirmaciones, las anotaciones que revelan la intención disminuyen los errores.
  • Repetirse de una manera que la máquina pueda verificar es a menudo una idea genial . De hecho, eso es una afirmación, y este uso de cast es una afirmación. Las afirmaciones siguen siendo la técnica más general que tenemos para obtener el código correcto, ya que a Turing se le ocurrió la idea hace muchos años.

Como se indicó, no es necesario para C, sino para C ++. Si cree que va a compilar su código C con un compilador de C ++, por alguna razón, puede usar una macro en su lugar, como:

#ifdef __cplusplus
# define NEW(type, count) ((type *)calloc(count, sizeof(type)))
#else
# define NEW(type, count) (calloc(count, sizeof(type)))
#endif

De esa manera, aún puede escribirlo de una manera muy compacta:

int *sieve = NEW(int, 1);

y se compilará para C y C ++.

Del Wikipedia :

  

Ventajas de emitir

     
      
  • La inclusión del elenco puede permitir que un programa o función C se compile como C ++.

  •   
  • El elenco permite versiones anteriores a 1989 de malloc que originalmente devolvieron un char *.

  •   
  • La conversión puede ayudar al desarrollador a identificar inconsistencias en el tamaño del tipo si el tipo de puntero de destino cambia, particularmente si el puntero se declara lejos de la llamada malloc () (aunque los compiladores modernos y los analizadores estáticos pueden advertir sobre tal comportamiento sin requerir el elenco).

  •   
     

Desventajas de lanzar

     
      
  • Bajo el estándar ANSI C, la conversión es redundante.

  •   
  • Agregar el reparto puede enmascarar la falla al incluir el encabezado stdlib.h , en   en el que se encuentra el prototipo de malloc. En ausencia de un   prototipo para malloc, el estándar requiere que el compilador de C   supongamos que malloc devuelve un int. Si no hay yeso, hay una advertencia   emitido cuando este entero se asigna al puntero; sin embargo, con   el elenco, esta advertencia no se produce, ocultando un error. En cierto   arquitecturas y modelos de datos (como LP64 en sistemas de 64 bits, donde   largo y los punteros son de 64 bits y int es de 32 bits), este error puede   en realidad resulta en un comportamiento indefinido, como lo declara implícitamente   malloc devuelve un valor de 32 bits, mientras que la función realmente definida   devuelve un valor de 64 bits. Dependiendo de las convenciones de llamadas y la memoria   diseño, esto puede resultar en la destrucción de la pila. Este problema es menos probable   pasar desapercibido en los compiladores modernos, ya que producen uniformemente   advertencias de que se ha utilizado una función no declarada, por lo que una advertencia   Todavía aparece. Por ejemplo, el comportamiento predeterminado de GCC es mostrar un   advertencia que dice " declaración implícita incompatible de incorporado   función " independientemente de si el elenco está presente o no.

  •   
  • Si el tipo de puntero se cambia en su declaración, uno puede   también, necesita cambiar todas las líneas donde se llama y lanza malloc.

  •   

Aunque malloc sin conversión es el método preferido y la mayoría de los programadores experimentados lo eligen , debe usar el que desee para tener conocimiento de los problemas.

es decir: si necesita compilar el programa C como C ++ (aunque esos son lenguaje separado), debe usar malloc con la conversión.

En C puede convertir implícitamente un puntero nulo a cualquier otro tipo de puntero, por lo que no es necesario un reparto. El uso de uno puede sugerir al observador casual que hay alguna razón por la que se necesita, lo que puede ser engañoso.

No lanzas el resultado de malloc, porque hacerlo agrega desorden inútil a tu código.

La razón más común por la que las personas arrojan el resultado de malloc es porque no están seguros de cómo funciona el lenguaje C.Esa es una señal de advertencia:Si no sabes cómo funciona un mecanismo de lenguaje en particular, entonces no Adivina.Búscalo o pregunta en Stack Overflow.

Algunos comentarios:

  • Un puntero vacío se puede convertir a/desde cualquier otro tipo de puntero sin una conversión explícita (C11 6.3.2.3 y 6.5.16.1).

  • Sin embargo, C++ no permitirá una conversión implícita entre void* y otro tipo de puntero.Entonces, en C++, la conversión habría sido correcta.Pero si programa en C++, debería usar new y no malloc().Y nunca deberías compilar código C usando un compilador de C++.

    Si necesita admitir C y C++ con el mismo código fuente, utilice modificadores del compilador para marcar las diferencias.No intentes saciar ambos estándares de lenguaje con el mismo código, porque no son compatibles.

  • Si un compilador de C no puede encontrar una función porque olvidó incluir el encabezado, obtendrá un error del compilador/enlazador al respecto.Entonces, si olvidaste incluir <stdlib.h> Eso no es gran cosa, no podrás construir tu programa.

  • En compiladores antiguos que siguen una versión del estándar que tiene más de 25 años, olvidándose de incluir <stdlib.h> resultaría en un comportamiento peligroso.Porque en ese antiguo estándar, las funciones sin un prototipo visible convertían implícitamente el tipo de retorno a int.Transmitir el resultado desde malloc explícitamente ocultaría este error.

    Pero eso realmente no es un problema.No estás usando una computadora de 25 años, entonces ¿por qué usarías un compilador de 25 años?

En C obtienes una conversión implícita de void* a cualquier otro puntero (de datos).

Enviando el valor devuelto por malloc() no es necesario ahora, pero me gustaría agregar un punto que parece que nadie ha señalado:

En la antigüedad, es decir, antes de que ANSI C proporcione el void * como el tipo genérico de punteros, char * es el tipo para dicho uso. En ese caso, el elenco puede cerrar las advertencias del compilador.

Referencia: Preguntas frecuentes sobre C

No es obligatorio emitir los resultados de malloc, ya que devuelve void*, y un <=> puede apuntar a cualquier tipo de datos.

Solo sumando mi experiencia, estudiando ingeniería informática veo que los dos o tres profesores que he visto escribiendo en C siempre echan malloc, sin embargo el que le pregunté (con un CV inmenso y conocimiento de C) me dijo que es absolutamente innecesario pero Solía ​​ser absolutamente específico y lograr que los estudiantes adoptaran la mentalidad de ser absolutamente específicos.Esencialmente, la conversión no cambiará nada en su funcionamiento, hace exactamente lo que dice, asigna memoria y la conversión no lo afecta, obtienes la misma memoria, e incluso si la transmites a otra cosa por error (y de alguna manera evades el compilador errores) C accederá a él de la misma manera.

Editar: El casting tiene cierto sentido.Cuando usas notación de matriz, el código generado tiene que saber cuántos lugares de memoria tiene que avanzar para llegar al comienzo del siguiente elemento, esto se logra mediante conversión.De esta manera sabes que para un doble avanzas 8 bytes mientras que para un int avanzas 4, y así sucesivamente.Por lo tanto, no tiene ningún efecto si utiliza notación de puntero; en notación de matriz se vuelve necesario.

Esto es lo que La referencia de la biblioteca GNU C el manual dice:

  

Puede almacenar el resultado de malloc en cualquier variable de puntero sin un   emitir, porque ISO C convierte automáticamente el tipo void * a otro   tipo de puntero cuando sea necesario. Pero el reparto es necesario en contextos.   que no sean operadores de asignación o si desea que se ejecute su código   en C. tradicional

Y, de hecho, el estándar ISO C11 (p347) lo dice:

  

El puntero devuelto si la asignación se realiza correctamente está alineado de manera adecuada   que puede asignarse a un puntero a cualquier tipo de objeto con un   requisito de alineación fundamental y luego utilizado para acceder a tal   objeto o una matriz de dichos objetos en el espacio asignado (hasta que el   el espacio se desasigna explícitamente)

Un puntero vacío es un puntero genérico y C admite la conversión implícita de un tipo de puntero vacío a otros tipos, por lo que no hay necesidad de escribirlo explícitamente.

Sin embargo, si desea que el mismo código funcione perfectamente compatible en una plataforma C ++, que no admite la conversión implícita, debe realizar la conversión de texto, por lo que todo depende de la usabilidad.

El tipo devuelto es nulo *, que se puede convertir al tipo deseado de puntero de datos para que no se pueda referenciar.

En el lenguaje C, se puede asignar un puntero nulo a cualquier puntero, por lo que no debe usar un tipo de conversión. Si desea & Quot; escriba safe & Quot; asignación, puedo recomendar las siguientes funciones de macro, que siempre uso en mis proyectos en C:

#include <stdlib.h>
#define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
#define NEW(ptr) NEW_ARRAY((ptr), 1)

Con estos en su lugar, simplemente puede decir

NEW_ARRAY(sieve, length);

Para matrices no dinámicas, la tercera macro de función imprescindible es

#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])

lo que hace que los bucles de matriz sean más seguros y convenientes:

int i, a[100];

for (i = 0; i < LEN(a); i++) {
   ...
}

Depende del lenguaje de programación y el compilador. Si usa malloc en C, no es necesario escribir cast, ya que escribirá automáticamente cast, sin embargo, si usa C ++, debe escribir cast porque void* devolverá un tipo <=>.

Las personas acostumbradas a GCC y Clang están en mal estado. No es tan bueno por ahí.

He estado bastante horrorizado a lo largo de los años por los compiladores asombrosamente viejos que me han requerido usar. A menudo, las empresas y los gerentes adoptan un enfoque ultraconservador para cambiar los compiladores y ni siquiera probarán si un nuevo compilador (con mejor cumplimiento de estándares y optimización de código) funcionará en su sistema. La realidad práctica para los desarrolladores que trabajan es que cuando estás codificando necesitas cubrir tus bases y, desafortunadamente, lanzar mallocs es un buen hábito si no puedes controlar qué compilador puede aplicarse a tu código.

También sugeriría que muchas organizaciones apliquen un estándar de codificación propio y que ese sea el método que la gente siga si se define. En ausencia de una guía explícita, tiendo a ir con mayor probabilidad de compilar en todas partes, en lugar de una servil adhesión a un estándar.

El argumento de que no es necesario según los estándares actuales es bastante válido. Pero ese argumento omite los aspectos prácticos del mundo real. No codificamos en un mundo regido exclusivamente por el estándar del día, sino por los aspectos prácticos de lo que me gusta llamar & Quot; campo de realidad de la administración local & Quot ;. Y eso está doblado y retorcido más de lo que nunca estuvo el tiempo espacial. :-)

YMMV.

Tiendo a pensar en lanzar malloc como una operación defensiva. No es bonito, no es perfecto, pero generalmente es seguro. (Honestamente, si no ha incluido stdlib.h, entonces tiene manera más problemas que lanzar malloc!).

Incluí la conversión simplemente para mostrar desaprobación por el feo agujero en el sistema de tipos, que permite que código como el siguiente fragmento se compile sin diagnóstico, aunque no se utilizan conversiones para provocar la mala conversión:

double d;
void *p = &d;
int *q = p;

Desearía que eso no existiera (y no existe en C++) y por eso lo lanzo.Representa mi gusto y mi política de programación.No sólo estoy emitiendo un indicador, sino que efectivamente estoy emitiendo un voto, y expulsando demonios de la estupidez.si no puedo de hecho expulsar la estupidez, entonces al menos permítanme expresar mi deseo de hacerlo con un gesto de protesta.

De hecho, una buena práctica es envolver malloc (y amigos) con funciones que regresan unsigned char *, y básicamente nunca usar void * en tu código.Si necesita un puntero genérico a cualquier objeto, utilice un char * o unsigned char *, y tienen yesos en ambas direcciones.La única relajación que se puede permitir, tal vez, es utilizar funciones como memset y memcpy sin yesos.

Sobre el tema de la conversión y la compatibilidad con C++, si escribe su código para que se compile como C y C++ (en cuyo caso tengo que emitir el valor de retorno de malloc al asignarlo a algo que no sea void *), puedes hacer algo muy útil por ti mismo:puede usar macros para la conversión que se traducen a conversiones de estilo C++ cuando se compila como C++, pero se reducen a una conversión de C cuando se compila como 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 cumple con estas macros, entonces un simple grep La búsqueda de estos identificadores en su base de código le mostrará dónde están todas sus conversiones, para que pueda revisar si alguna de ellas es incorrecta.

Luego, en el futuro, si compila regularmente el código con C++, exigirá el uso de una conversión adecuada.Por ejemplo, si usas strip_qual solo para eliminar un const o volatile, pero el programa cambia de tal manera que ahora implica una conversión de tipo, obtendrá un diagnóstico y tendrá que usar una combinación de conversiones para obtener la conversión deseada.

Para ayudarle a cumplir con estas macros, el compilador GNU C++ (¡no C!) tiene una hermosa característica:un diagnóstico opcional que se produce para todas las ocurrencias de modelos estilo C.

     -Wold-style-cast (C++ and Objective-C++ only)
         Warn if an old-style (C-style) cast to a non-void type is used
         within a C++ program.  The new-style casts (dynamic_cast,
         static_cast, reinterpret_cast, and const_cast) are less vulnerable
         to unintended effects and much easier to search for.

Si su código C se compila como C++, puede usar esto -Wold-style-cast opción para conocer todas las ocurrencias del (type) convertir la sintaxis que pueda infiltrarse en el código y realizar un seguimiento de estos diagnósticos reemplazándola con una opción adecuada entre las macros anteriores (o una combinación, si es necesario).

Este tratamiento de las conversiones es la mayor justificación técnica independiente para trabajar en un "Clean C":el dialecto combinado de C y C++, que a su vez justifica técnicamente la conversión del valor de retorno de malloc.

Lo mejor que se puede hacer al programar en C siempre que sea posible:

  1. Haga que su programa se compile a través de un compilador de C con todas las advertencias activadas -Wall y corregir todos los errores y advertencias
  2. Asegúrese de que no haya variables declaradas como auto
  3. Luego compílelo usando un compilador de C++ con -Wall y -std=c++11.Corrija todos los errores y advertencias.
  4. Ahora compila usando el compilador de C nuevamente.Su programa ahora debería compilarse sin previo aviso y contener menos errores.

Este procedimiento le permite aprovechar la estricta verificación de tipos de C++, reduciendo así la cantidad de errores.En particular, este procedimiento le obliga a incluir stdlib.ho obtendrás

malloc no fue declarado dentro de este alcance

y también te obliga a lanzar el resultado de malloc o obtendrás

conversión no válida de void* a T*

o cualquiera que sea su tipo de objetivo.

Los únicos beneficios que puedo encontrar al escribir en C en lugar de C++ son

  1. C tiene un ABI bien especificado
  2. C++ puede generar más código [excepciones, RTTI, plantillas, tiempo de ejecución polimorfismo]

Tenga en cuenta que, en el caso ideal, la segunda desventaja debería desaparecer cuando se utiliza el subconjunto común a C junto con el estático característica polimórfica.

Para aquellos que encuentran inconvenientes las reglas estrictas de C++, podemos usar la función C++ 11 con tipo inferido.

auto memblock=static_cast<T*>(malloc(n*sizeof(T))); //Mult may overflow...

No, no emites el resultado de malloc().

En general, no envía contenido desde o hacia void * .

Una razón típica dada para no hacerlo es que la falla en #include <stdlib.h> podría pasar desapercibida. Esto ya no es un problema desde hace mucho tiempo ya que C99 hizo que las declaraciones de función implícitas sean ilegales, por lo que si su compilador cumple al menos con C99, recibirá un mensaje de diagnóstico.

Pero hay una razón mucho más fuerte para no introducir lanzamientos de puntero innecesarios:

En C, una conversión de puntero casi siempre es un error . Esto se debe a la siguiente regla ( & # 167; 6.5 p7 en N1570, el último borrador para C11):

  

Un objeto tendrá su valor almacenado accedido solo por una expresión lvalue que tenga uno de   los siguientes tipos:
  & # 8212; un tipo compatible con el tipo efectivo del objeto,
  & # 8212; una versión calificada de un tipo compatible con el tipo efectivo del objeto,
  & # 8212; un tipo que es el tipo con signo o sin signo correspondiente al tipo efectivo del   objeto,
  & # 8212; un tipo que es el tipo con signo o sin signo correspondiente a una versión calificada del   tipo efectivo del objeto,
  & # 8212; un tipo agregado o de unión que incluye uno de los tipos antes mencionados entre sus   miembros (incluido, recursivamente, un miembro de una unión agregada o contenida), o
  & # 8212; un tipo de personaje.

Esto también se conoce como la regla de alias estricto . Entonces, el siguiente código es comportamiento indefinido :

long x = 5;
double *p = (double *)&x;
double y = *p;

Y, a veces sorprendentemente, lo siguiente también es:

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;

A veces, necesita lanzar punteros, pero dada la estricta regla de alias , debe tener mucho cuidado con ella. Por lo tanto, cualquier aparición de un puntero emitido en su código es un lugar en el que debe verificar nuevamente su validez . Por lo tanto, nunca escribe un molde de puntero innecesario.

tl; dr

En pocas palabras: como en C, cualquier aparición de puntero emitido debería levantar una bandera roja para el código que requiere atención especial, nunca debe escribir innecesario lanzamientos de puntero.


Notas al margen:

  • Hay casos en los que realmente necesita un reparto a printf(), p. si desea imprimir un puntero:

    int x = 5;
    printf("%p\n", (void *)&x);
    

    La conversión es necesaria aquí, porque <=> es una función variada, por lo que las conversiones implícitas no funcionan.

  • En C ++, la situación es diferente. La conversión de tipos de puntero es algo común (y correcto) cuando se trata de objetos de clases derivadas. Por lo tanto, tiene sentido que en C ++, la conversión ay desde <=> sea no implícita. C ++ tiene un conjunto completo de diferentes sabores de fundición.

Prefiero hacer el yeso, pero no manualmente.Mi favorito es usar g_new y g_new0 macros de simplista.Si no se usa simplista, agregaría macros similares.Esas macros reducen la duplicación de código sin comprometer la seguridad de tipos.Si escribe mal el tipo, obtendrá una conversión implícita entre punteros no vacíos, lo que provocará una advertencia (error en C++).Si olvida incluir el encabezado que define g_new y g_new0, obtendrías un error. g_new y g_new0 ambos toman los mismos argumentos, a diferencia malloc eso requiere menos argumentos que calloc.Solo agrega 0 para obtener memoria inicializada a cero.El código se puede compilar con un compilador de C++ sin cambios.

La conversión es solo para C ++ no C. En caso de que esté utilizando un compilador de C ++, es mejor que lo cambie a compilador de C.

El concepto detrás del puntero void es que se puede convertir a cualquier tipo de datos, por eso malloc devuelve void. También debe tener en cuenta el encasillado automático. Por lo tanto, no es obligatorio lanzar el puntero, aunque debe hacerlo. Ayuda a mantener limpio el código y ayuda a la depuración

  1. Como se indicó, no es necesario para C, sino para C ++.

  2. La inclusión del elenco puede permitir que un programa o función C se compile como C ++.

  3. En C es innecesario, ya que void * se promociona de forma automática y segura a cualquier otro tipo de puntero.

  4. Pero si lanzas entonces, puede ocultar un error si olvidaste incluir stdlib.h . Esto puede causar bloqueos (o, peor aún, no causar un bloqueo hasta mucho más tarde en una parte totalmente diferente del código).

    Porque stdlib.h contiene el prototipo de malloc se encuentra. En el ausencia de un prototipo para malloc, el estándar requiere que el C el compilador asume que malloc devuelve un int. Si no hay yeso, un se emite una advertencia cuando este entero se asigna al puntero; sin embargo, con el reparto, esta advertencia no se produce, ocultando un error.

Un puntero vacío es un puntero genérico y C admite la conversión implícita de un tipo de puntero vacío a otros tipos, por lo que no hay necesidad de escribirlo explícitamente.

Sin embargo, si desea que el mismo código funcione perfectamente compatible en una plataforma C ++, que no admite la conversión implícita, debe realizar la conversión de texto, por lo que todo depende de la usabilidad.

La conversión de malloc es innecesaria en C pero obligatoria en C ++.

La transmisión es innecesaria en C debido a:

  • void * se promociona de forma automática y segura a cualquier otro tipo de puntero en el caso de C.
  • Puede ocultar un error si olvidó incluir <stdlib.h>. Esto puede causar bloqueos.
  • Si los punteros y los enteros tienen un tamaño diferente, entonces está ocultando una advertencia al emitir y puede perder partes de su dirección devuelta.
  • Si el tipo de puntero se cambia en su declaración, también es posible que deba cambiar todas las líneas donde se llama y se lanza malloc.

Por otro lado, la transmisión puede aumentar la portabilidad de su programa. es decir, permite que un programa o función C se compile como C ++.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top