variable ¿Por qué puedo convertir implícitamente un int literal a un int*en C pero no en C++?




variable long (4)

Creí que en el siguiente código, C "automáticamente arroja 17 a un int * " que, como alguien señaló recientemente (pero no dio los motivos de por qué), es incorrecto.

int *ptoi = 17; // I assumed that 17 is being automatically casted to int *

Sé que si hago lo mismo que arriba en C ++, aparece un error que invalid conversion from int to int * . Pero si hago lo siguiente en C ++, funciona bien:

int *ptoi = (int *)17;

Estas son las razones por las que pensé que en C, el casting estaba implícito.

¿Puede alguien explicar por qué, en C ++, tengo que lanzarlo pero en C, funciona bien?


Las conversiones de enteros a punteros sin moldes también son ilegales en C. Sin embargo, la mayoría de los compiladores le permitirán salirse con la suya. Clang da una advertencia:

example.c:5:8: warning: incompatible integer to pointer conversion initializing
      'int *' with an expression of type 'int'
  int *x = 17;
       ^   ~~

C99 dice en la Sección 6.5.4 Operadores de elenco , párrafo 4:

Las conversiones que implican punteros, distintas de las permitidas por las restricciones de 6.5.16.1, se especificarán mediante un modelo explícito.

6.5.16.1 es la excepción para la conversión de void * a otros punteros sin necesidad de un molde.

La especificación de C ++ dice en la Sección 5.4 Conversión de tipo explícito (notación de lanzamiento) , párrafo 3:

Cualquier conversión de tipo no mencionada a continuación y no definida explícitamente por el usuario está mal formada.

Así que ahí lo tienes, es ilegal en ambos idiomas, pero por compatibilidad con un montón de software antiguo, muchos compiladores de C te permitirán salirte con la tuya.


Sí, el casting está implícito en C, aunque muchos (¿todos?) Compiladores dan una advertencia. En C ++, no se realiza ninguna conversión implícita de int a int* , por lo que se requiere el envío explícito.


Ha sido, C tiene conversiones implícitas, según mi experiencia, prácticamente de cualquier tipo integral a cualquier otro tipo integral. Los punteros en C se consideran tipos scalar integrales .

En C ++, los tipos integrales se definen de la siguiente manera:

Los tipos bool , char , char16_t , char32_t , wchar_t y los tipos enteros con unsigned y unsigned signo se denominan colectivamente tipos integrales. 48 Un sinónimo para el tipo integral es tipo entero. Las representaciones de tipos integrales definirán valores mediante el uso de un sistema de numeración binario puro. 49 [Ejemplo: esta Norma Internacional permite el complemento de 2, el complemento de 1 y las representaciones de magnitud firmadas para tipos integrales. -Final ejemplo]

El único valor integral que se puede convertir a tipo de puntero en C ++ es la constante de puntero nulo , aunque técnicamente la conversión es a un prvalue de tipo std::nullptr_t . (párrafo 4.10)

Nota final

En lugar de arreglarlo así:

int *ptoi = (int *)17;

considerando agregar el elenco estilo C ++:

int *ptoi = reinterpret_cast<int*>(17);

para aclarar qué tipo de conversión está tratando de invocar


El compilador interpretará int *ptoi = 17; como una variable ptoi que apunta a un número entero en la ubicación 17 (0x00000011).

C es simplemente un lenguaje completamente diferente. Puede parecer C ++, pero no lo es. Se aplican diferentes reglas a ambos idiomas.

Probablemente debería señalar que tanto C como C ++ (hasta donde sé) lo convierten en un puntero a 0x00000011, pero C simplemente se queja menos, ya que la asignación de ubicaciones de memoria es algo que no es inválido en C.





casting