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

467
Visualizações
Cómo actualizar una estructura C/C++ con compatibilidad

Tengo una struct definida en una biblioteca histórica con, lamentablemente, una desafortunada elección de tipo: unsigned char * en lugar de char* .

 struct MyStruct { unsigned char * myMember; };

Esta struct es utilizada por una gran cantidad de aplicaciones C y, cada vez más, por aplicaciones C++. Esas aplicaciones C++ generan un error cuando se usan con strlen , por ejemplo, obligándonos a emitir. Muchos moldes.

Me gustaría remediar eso.

Pero una cosa es extremadamente importante: debe ser absolutamente compatible sin modificaciones y no tener impacto en los proyectos existentes.

Pensé en hacer un union . Por desgracia, mi variable no puede tener el mismo nombre.

 struct MyStruct { union { unsigned char * myMember; // char * myMember; Obvioulsy, rejected by the compiler. };

Me temo que no hay ninguna solución obvia. ¿Me equivoco?

No puedo cambiar el tamaño de la estructura porque está asignada en una memoria compartida de tamaño inalterable.

over 4 years ago · Santiago Trujillo
5 Respostas
Responde à pergunta

0

Dado que su objetivo es crear una isla de perfección y no arreglar el mundo, podría crear un adaptador con un constructor implícito a partir de esta estructura anterior y usar ese adaptador en el código de "isla de perfección".

 struct BetterMyStruct { char* myMember; BetterMyStruct(MyStruct const& x): myMember((char*)x.myMember) { // any ugly secret hacks you want or need } }; ... size_t better_strlen(BetterMyStruct const& x) { // perfect function return std::string_view(x.myMember).size(); } ... better_strlen(MyStruct(...)); // perfect function invocation on imperfect inputs
over 4 years ago · Santiago Trujillo Relatório

0

Hay un remedio más simple. A menudo, cuando está molesto por tener que hacer algo demasiadas veces, simplemente puede resolverlo haciendo eso una vez dentro de una función:

 std::size_t unsigned_strlen(const unsigned char* str) noexcept { return std::strlen(reinterpret_cast<const char*>(str)); }
over 4 years ago · Santiago Trujillo Relatório

0

Dado que puede cambiar MyStruct , le sugiero que simplemente elimine unsigned , lo que rompería el ABI existente y requeriría la recompilación de todo lo que usa la estructura.

Si esa no es una opción por algún motivo, puede heredar la estructura original y proporcionar un método getter para las aplicaciones de C++.

 // use this in C apps struct MyStruct { unsigned char* myMember; }; // use this in C++ apps struct MyStructCpp : MyStruct { MyStructCpp(const MyStruct& rhs) : MyStruct(rhs) {} char* myMemberAsChar() const { return reinterpret_cast<char*>(myMember); } };
over 4 years ago · Santiago Trujillo Relatório

0

Nota: No puede resolver esto en C++, porque a C estricto tampoco le gustan los unsigned char* . Incluso con la configuración laxa del compilador de C, obtendría (ejemplo con la configuración predeterminada de gcc):

los objetivos del puntero en la asignación difieren en el signo [-Wpointer-sign]|

incluso cuando se hace algo básico como una asignación simple ms.myMember="hello"; .

Aquí hay una solución C11.

 struct MyStruct { union // anonymous union { unsigned char * myMember; char* myCharMember; }; }; #define myMember myCharMember

Código de prueba:

 struct MyStruct ms; _Generic(ms.myMember, char*: puts("I'm a char*"), unsigned char*: puts("I'm an unsigned char*"));

Sin el #define y te dirá "I'm an unsigned char*" , pero con el #define , "I'm a char*" .

over 4 years ago · Santiago Trujillo Relatório

0

No hay forma de que myMember sea un char* o cualquier otro tipo sin potencialmente romper los proyectos existentes, por la simple razón de que su tipo puede deducirse

 void foo(decltype(MyStruct::myMember));

Esto causará problemas de ABI, el más leve de los cuales es un error del enlazador.

La medida media es proporcionar una abreviatura para el elenco.

 struct MyStruct { #ifdef __cplusplus char* signed_myMember() { return (char*)myMember; } #endif };

Afortunadamente, char puede crear alias de cualquier cosa en C++, lo que lo hace legal.

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