¿Cómo escribir código portable en c ++?

¿Cuáles son las cosas que debo tener en cuenta para escribir código portátil? Como soy un principiante en C ++, quiero practicarlo desde el principio.

Gracias.

  • aprende a usar la biblioteca estándar
  • leer libros (por ejemplo, este )
  • cuando tienes experiencia, aprende a usar boost

Mantenga el código específico de la plataforma separado del código reutilizable, preferiblemente en un archivo diferente, pero al menos en una función diferente. Si comienza a tener #if WIN32 y #if CYGWIN y #if BSD todas partes, tendrá una pesadilla de mantenimiento.

Luego, comstack al menos dos plataformas diferentes temprano y con frecuencia. Las opciones típicas son Visual C ++ en Windows y gcc en Linux. Dado que ni las bibliotecas del sistema ni el comstackdor se comparten, se detectará el código no portátil antes de que se arraigue profundamente en su diseño.

¿Cuáles son las cosas que debo tener en cuenta para escribir código portátil?

  1. Mantenga varios comstackdores cerca, pruebe el código regularmente en las plataformas de destino. Si está haciendo un software multiplataforma para Windows Windows / Linux, manténgase cerca de mingw, visual studio express (es decir, “comstackdor de microsoft”) y una instalación de Linux con g ++ (o use la máquina virtual). Incluso si tu código es perfecto, el comstackdor podría tener algún tipo de peculiaridad inesperada. Por ejemplo, ciertas versiones del comstackdor ms tienen un límite en los tamaños de las constantes de cadena, que no tiene gcc.
  2. No confíe en los tamaños de los tipos estándar. Por ejemplo, en msvc sizeof (wchar_t) es de 2 bytes. En la instalación de Linux, puede ser de 4 bytes. Use sizeof (si lo necesita), o trate de evitar tener que usar el tamaño de cualquier tipo en su código. Y no debe suponer que el puntero tiene 4 bytes de tamaño (pasando el puntero de datos de usuario al escenario de llamada de API): tendrá 8 bytes en 64 bits.
  3. No use pragmas, macros y extensiones específicos del comstackdor. Por ejemplo, evite “#pragma una vez”.
  4. No use extensiones a la biblioteca estándar (proporcionada por el desarrollador del comstackdor). Esto es más aplicable a las funciones de la biblioteca C, sin embargo. Por ejemplo, el comstackdor de MS proporciona múltiples versiones “seguras” (como strcpy_s) de las rutinas estándar de estilo C. Que, por supuesto, no estará disponible en otras plataformas.
  5. Tenga mucho cuidado si decide usar rutinas estilo C (como sprintf) en código C ++. ( que se supone que es una mala práctica, pero en algunos casos esto es útil). Tienen implementaciones, extensiones y diferentes parámetros diferentes. Por ejemplo, sprintf puede tener diferentes formatos adicionales que se implementan de manera diferente en diferentes plataformas. Por ejemplo, la última vez que comprobé que “% S” se comporta de forma diferente en msvc y gcc en la rutina vswprintf.
  6. No confíe en tipos de datos específicos del comstackdor, como __int32. Es muy probable que necesite algún tipo de tipo garantizado de 4 bytes de longitud (o algo así): use typedef combinado con comstackción condicional (“#ifdef WIN32”). O utilice tipos proporcionados por la biblioteca multiplataforma. Por ejemplo, SDL proporciona tipos como Uint8, Qt 4 tiene quint32, etc. Esta es una práctica bastante común.
  7. Evite las llamadas directas al sistema operativo. Use funciones estándar para acceder a los archivos.
  8. Cuando tenga que usar llamadas específicas del sistema operativo, use la comstackción condicional (#ifdef WIN32, etc.)
  9. Intenta usar el mismo sistema de comstackción en todas las plataformas. No hay MSBuild en Linux. Use gnumake, cmake, scons o qmake. Mientras que en algunos de esos sistemas tendrás que codificar en flags para comstackdores diferentes, será posible usar el mismo script en todas partes. Por ejemplo, funciona muy bien con SConstructs. Y mantener un script de construcción para todas las plataformas puede ser más fácil que sincronizar los cambios en los diferentes sistemas de comstackción.
  10. Para todas las operaciones que requieren interacción con el sistema operativo (Gui, manipulación de archivos), use bibliotecas multiplataforma. Qt es una buena elección.

Escriba los progtwigs de línea de comando para comenzar. Cuando esté listo, busque un juego de herramientas de ventanas multiplataforma como Qt .

Si está interesado en escribir código multilingüe, use una biblioteca Unicode de terceros, como ICU, en lugar de confiar en las bibliotecas específicas de la plataforma.

Use los tipos de STL cuando sea posible. Tenga cuidado al usar tipos y API dependientes del sistema. Por ejemplo, no use tipos como UINT y DWORD en Windows.

Puede usar una biblioteca como refuerzo para que le sea más fácil escribir código portátil. Si necesita una GUI, considere usar un conjunto de herramientas multiplataforma como Qt.

Algunas veces necesitará escribir un código específico para la plataforma, y ​​en esos casos puede hacer algo como esto:

 #ifdef _WIN32 #include  #else #include  #endif 

El progtwigdor incauto es probable que entre en un montón de trampas, que podemos intentar categorizar. Pero déjame decirte primero: como un absoluto es imposible.

El problema es que incluso el código de conformidad estándar podría no ser portátil debido a un problema particular del comstackdor.

Ahora estas son las principales categorías que puedo pensar en la parte superior de mi cabeza.

Extensiones del comstackdor

Como por ejemplo el uso de matrices de variables:

 void func(int const n) { int array[n]; } 

Esto no es estándar, pero muchos comstackdores lo admiten, no obstante, porque es simplemente práctico.

Extensiones de bibliotecas estándar

Muchas implementaciones de bibliotecas estándar proporcionan un std::hash_map que nunca se especificó. Si lo usa en su código, no es portátil.

La tendencia moderna es esconder esto en el std::tr1 nombres std::tr1 para que los progtwigdores sepan que se trata de una extensión.

También tenga en cuenta que muchos definen typedef o macros que no son generics (por ejemplo, PRETTY_FUNCTION ). El estándar no especifica ninguna macro, y muy pocos typedef son.

Plataforma específica

Por ejemplo, el tamaño y la alineación de int o double no están especificados en el estándar. Si haces bit-twiddling y esperas que tenga 32 bits, estarás atornillado a las plataformas de 64 bits incluso sin cambiar tu comstackdor.

Plataforma API

Nuestros progtwigs están destinados a comstackrse y, a menudo, están destinados a interactuar con la computadora en la que se ejecutan:

  • para acceder al hardware
  • para acceder al sistema de archivos
  • para acceder a la pantalla

Debe encontrar las API portátiles multiplataforma o hacer las suyas propias. Verifique algunas bibliotecas en la lista a continuación.

Bibliotecas

La mayoría de las bibliotecas bien escritas son en gran medida portátiles, solo asegúrese de que sean compatibles con:

  • los comstackdores que le interesan
  • las plataformas en las que estás interesado

Las buenas bibliotecas implican:

  • Apache (la colección de bibliotecas)
  • Aumentar
  • Qt (por gráfico)
  • ICU (para manejo Unicode)

Los otros que necesita revisar … y eso lleva tiempo.

No creo que haya una respuesta perfecta allí. Pero como la portabilidad perfecta no es posible, debe decidir qué comstackdores y plataforma desea admitir.

Para la plataforma, debe comenzar con Windows y un sabor Linux. Para los comstackdores, elija dos (con Comeau si puede pagarlo).

Algunas pautas:

  1. Mantenga el extremo comercial del código y la GUI por separado.
  2. Evite el uso de muletas específicas del comstackdor (#pragma, etc.)
  3. Use expresiones convencionales que no cambien el comportamiento con el comstackdor / plataforma en lugar de trucos de manipulación de bits lindos.
  4. Si toca hardware, pertenece a un controlador de dispositivo.
  5. Use encabezados de tipo de datos como types.h (uint32_t, etc.).
  6. Use una capa de abstracción del sistema operativo para no llamar directamente al sistema operativo.

A veces hay que sacrificar eficiencia y rendimiento para ganar portabilidad. Por ejemplo, si su código requiere acceder a los campos desde un búfer, siempre puede lanzar una estructura empaquetada al puntero del búfer. Pero eso es terriblemente no portátil. Por lo tanto, en su lugar, necesita utilizar punteros con nombre calculados con compensaciones, a veces con código de manejo de alineación de límites. No es bonito, pero es portátil. Afortunadamente, puedes ocultar muchas de esas cosas con un uso juicioso de las interfaces de clase.

No todo el código debe escribirse de esa manera. Si diseña su aplicación de una manera muy modular con límites de responsabilidad bien definidos, entonces el 90-95% del código puede ser portátil sin dolor. Luego, solo aísle el 5-10% en un área muy localizada que debería personalizarse para una nueva plataforma.

Otros lo dijeron antes, pero aquí está mi opinión al respecto:

1) ¿Necesitas C ++? No es el mejor lenguaje para escribir código portátil porque está cerca del metal desnudo. Java, Python, Perl, PHP o Javascript pueden ser mejores para ti.

2) Si necesita C ++, no intente escribir código completamente portátil, de todos modos es casi imposible. En su lugar, decida primero qué plataformas desea admitir. Por ejemplo: Linux, MacOS X, Windows

3) Asegúrese de probar su código en todas las plataformas seleccionadas continuamente. No solo cree en Windows y espere simplemente comstackr una versión de Linux ‘cuando esté listo’. Comstack todas las plataformas a diario y asegúrate de seguir analizándolas en busca de problemas.

Para aprender, trate de evitar libros que se concentren en una implementación. En algunos casos, la introducción o un capítulo temprano le darán algunas instrucciones sobre cómo obtener o usar una implementación de idioma; si menciona más de una implementación, probablemente estés bien.

Obtenga un libro de referencia que sea independiente de la plataforma. El lenguaje de progtwigción C ++ de Stroustrup es una buena referencia, aunque no es un buen libro para que un principiante intente aprender de él. No confíe en referencias para una implementación dada. MSDN es útil, por ejemplo, pero su enfoque principal es cómo escribir progtwigs de Windows usando Visual C ++, no cómo escribir progtwigs que se comstackrán y ejecutarán en cualquier lugar.

Para escribir algo realmente útil, tendrá que entrar en un código no portátil. Trate de adquirir el hábito de separar el código de la interfaz de usuario de todo lo demás, ya que es donde tendrá la menor compatibilidad. Cuanto menos código tenga que cambiar entre plataformas, más portátil será su código.

Si puede, compile todo su código con al menos dos comstackdores diferentes.

El código independiente del sistema operativo es sorprendentemente difícil de hacer en C ++. Considera este ejemplo trivial:

 #include  int main(int argc, char** argv) { std::cout << argv[0] << std::endl; } 

Eso es C ++ perfectamente válido, aún no es portable porque no aceptará argumentos de línea de comandos Unicode en Windows. La versión correcta para Windows sería:

 #include  int wmain(int argc, wchar_t** argv) { std::wcout << argv[0] << std::endl; } 

Por supuesto, eso no es portable, funciona solo en Windows y no es estándar. De hecho, ni siquiera puede escribir una función main() portable main() en C ++ sin recurrir a la comstackción condicional.

una buena idea es usar las llamadas al sistema POSIX. De esta forma, no tendrá que lidiar con diferentes formas de crear subprocesos o usar mutexes y señales.

el problema es que Windows no es exactamente compatible con POSIX, pero hay bibliotecas que implementan ciertas características de POSIX, como esta: [1]: http://sourceware.org/pthreads-win32/