error: el lanzamiento de ‘void *’ a ‘int’ pierde precisión

Tengo una función con prototype void* myFcn(void* arg) que se usa como punto de partida para pthread. Necesito convertir el argumento en una int para su uso posterior:

 int x = (int)arg; 

El comstackdor (GCC versión 4.2.4) devuelve el error:

 file.cpp:233: error: cast from 'void*' to 'int' loses precision 

¿Cuál es la forma correcta de lanzar esto?

Puede convertirlo a un tipo intptr_t . Es un tipo int garantizado para ser lo suficientemente grande como para contener un puntero. Use #include para definirlo.

Una vez más, todas las respuestas anteriores omitieron el punto mal. El OP quería convertir un valor de puntero a un valor int, en cambio, la mayoría de las respuestas, de una forma u otra, intentaron convertir incorrectamente el contenido de los puntos arg a un valor int. Y, la mayoría de estos ni siquiera funcionan en gcc4.

La respuesta correcta es, si a uno no le importa perder precisión de datos,

 int x = *((int*)(&arg)); 

Esto funciona en GCC4.

La mejor manera es, si se puede, no hacer tal conversión, en cambio, si la misma dirección de memoria debe compartirse para puntero e int (por ejemplo, para guardar RAM), use union y asegúrese de que si se trata la dirección de la memoria como int. solo si sabes que se configuró por última vez como int.

No hay una forma adecuada de convertir esto a int en caso general. La biblioteca estándar C99 proporciona intptr_t y uintptr_t , que se supone deben usarse siempre que se necesite realizar tal uintptr_t . Si su biblioteca estándar (incluso si no es C99) proporciona estos tipos, utilícelos. De lo contrario, verifique el tamaño del puntero en su plataforma, defina estos tipos de letra de acuerdo con usted y utilícelos.

Lanzar un puntero a void * y volver es uso válido de reinterpret_cast <>. Entonces podrías hacer esto:

 pthread_create(&thread, NULL, myFcn, new int(5)); // implicit cast to void* from int* 

Luego en myFcn:

 void* myFcn(void* arg) { int* data = reinterpret_cast(arg); int x = *data; delete data; 

Nota: Como sbi señala, esto requeriría un cambio en la llamada OP para crear el hilo.

Lo que estoy tratando de enfatizar es que la conversión de int a puntero y viceversa puede verse afectada por problemas a medida que se mueve de una plataforma a otra. PERO convertir un puntero a void * y viceversa está bien soportado (en todas partes).

Por lo tanto, como resultado, puede ser menos propenso a errores generar un puntero dinámicamente y usar eso. Recordando borrar el puntero después de su uso para que no se filtre.

En lugar de:

 int x = (int)arg; 

utilizar:

 int x = (long)arg; 

En la mayoría de las plataformas, los punteros y los largos son del mismo tamaño, pero los puntos y los punteros a menudo no tienen el mismo tamaño en las plataformas de 64 bits. Si convierte ( void* ) a ( long ) no se pierde precisión, entonces asignando el ( long ) a un ( int ), trunca apropiadamente el número para encajar.