Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

228
Visualizações
definición de tipo de un puntero reconocido por C a una clase interna de C++

Tengo una clase que quiero compartir entre C y C++, donde C solo puede obtenerla como un puntero. Sin embargo, debido a que es una clase interna, no se puede declarar hacia adelante. En cambio, esto es lo que hace nuestro código actual en un archivo de encabezado común:

 #ifdef __cplusplus class Container { public: class Object { public: int x; }; }; typedef Container::Object * PObject; #else typedef void* PObject; #endif

Parece que esto viola la regla de una definición (ODR), porque C y C++ ven una definición diferente usando #ifdef . Pero debido a que esto es un puntero, no estoy seguro de si esto crea un problema real o no. C solo usa el puntero para pasarlo a las funciones de C++, no hace nada directamente con él. Por ejemplo, este código en el archivo de encabezado común:

 #ifdef __cplusplus extern "C" { #endif int object_GetX(PObject pObject); #ifdef __cplusplus } #endif /* __cplusplus */

Así es como lo implementamos en el archivo C++:

 int object_GetX(PObject pObject) { return pObject->x; }

Mis preguntas son:

  1. ¿Violar la ODR de esta manera causaría algún problema real?
  2. Si es así, ¿hay otra forma conveniente de compartir la clase con C?
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

En primer lugar, los punteros de alias de tipo suelen ser una receta para los problemas.
no lo hagas

En segundo lugar, la clase "interna" es un concepto usado en exceso, por lo que mi primer reflejo sería considerar si es realmente necesario.

Si es necesario, puede definir un tipo vacío opaco y derivar de él para alguna seguridad de tipo:

En un encabezado compartido:

 struct OpaqueObject; #ifdef __cplusplus extern "C" { #endif int object_GetX(OpaqueObject* pObject); #ifdef __cplusplus } #endif /* __cplusplus */

En un encabezado de C++:

 struct OpaqueObject {}; class Container { public: class Object : public OpaqueObject { public: int x; }; };

Implementación:

 int object_GetX(OpaqueObject* pObject) { return static_cast<Container::Object*>(pObject)->x; }
over 4 years ago · Santiago Trujillo Relatório

0

¿Violar la ODR de esta manera causaría algún problema real?

¿"Problemas reales"? Quizás. Tal vez no.

No existe una "regla ODR mixta C/C++". Las reglas están "contenidas" dentro de un lenguaje de programación, las especificaciones están escritas para un lenguaje de programación. C++ tiene sus propias reglas y C++ ihas regla ODR. C tiene sus propias reglas y C no sabe nada sobre ODR. Otros lenguajes de programación tienen sus propias reglas.

No está violando ODR en C ++: C ++ ve una sola definición de Contenedor en todas partes.

El material en extern "C" usa la convención de llamadas C, que podría suponer que también se adhiere al lenguaje C. En este caso, simplemente está violando la regla https://port70.net/~nsz/c/c11/n1570.html#6.5.2.2p9 . Digamos que esto es como ODR en C para funciones.

Si no, estás violando algo entre idiomas, eso sería ABI. Pasas el valor de un puntero void * del lado C y tu función lee un valor del puntero Container::Object * del lado C++. Eso podría estar permitido por el ABI específico que usan sus compiladores, podría no estar especificado. El enfoque seguro sería asumir que no está permitido.

¿Hay otra forma conveniente de compartir la clase con C?

El lenguaje C también ofrece verificación de tipo estático al igual que C++, pero al usar void * básicamente lo está desactivando. No mezcle C ++ con C. Solo tenga un nombre único diferente para el lado C, estará mucho menos confundido.

Además, pObject vs PObject ? ¡Tu turno debe ser rápido!

 // object.hpp #ifdef __cplusplus class Container { public: class Object { public: int x; }; }; typedef Container::Object PObject; extern "C" { #endif struct C_PObject { void *pnt; }; int object_GetX(struct C_PObject obj); // ... // object_c.cpp PObject *object_from_c(struct C_PObject obj) { return reinterpret_cast<PObject *>(obj.pnt); } extern "C" int object_GetX(struct C_PObject obj) { return object_from_c(obj)->x; }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda