¿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.Cómo escribir código portable en C++?
Gracias.
¿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.Cómo escribir código portable en C++?
Gracias.
Además, libros como estos: http: // stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list –
Entonces, ¿cómo exactamente el impulso está relacionado con la portabilidad? – SigTerm
@SigTerm: uno de los principales objetivos de diseño de boost es la portabilidad. funcionará en una amplia variedad de plataformas, y hace un buen trabajo de abstracción de las diferencias. Por ejemplo, las bibliotecas de subprocesos y las bibliotecas de sistemas de archivos funcionan de forma independiente de la plataforma. Algunas de estas cosas están incluidas en C++ 0x. – rmeador
Utilice 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.
A veces será necesario escribir código específico de la plataforma, y en esos casos se puede hacer algo como esto:
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
Comentario programas de línea de comando para comenzar. Cuando esté listo, busque un juego de herramientas de ventana multiplataforma como Qt.
Si le interesa escribir código multilingüe, use una biblioteca Unicode de terceros, como ICU, en lugar de basarse en bibliotecas específicas de la plataforma.
... Y si maneja el texto, preocúpese por lo multilingüe. –
La UCI es un punto muy bueno ya que C++ no tiene un tipo de datos de cadena real (con reconocimiento de Unicode). En los sistemas tipo Unix 'std :: string' a menudo funciona, en Windows' std :: wstring' siempre funciona, pero para los programas realmente independientes del sistema operativo necesita un tipo de datos de cadena real como 'UnicodeString' de ICU. – Philipp
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 consulta que sea independiente de la plataforma. Stroustrup's El lenguaje de programación C++ 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 programas de Windows usando Visual C++, no cómo escribir programas que se compilarán y ejecutarán en cualquier lugar.
Para escribir algo realmente útil, tendrá que ingresar en un código que no sea 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.
El programador 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 compilador.
Ahora aquí están las principales categorías que puedo pensar en la parte superior de mi cabeza.
extensiones del compilador
Como por ejemplo el uso de variables de matrices:
void func(int const n)
{
int array[n];
}
Esto no es estándar, pero muchos compiladores lo apoyan, sin embargo, porque es sólo práctico.
bibliotecas extensiones estándar
Muchas implementaciones de librerías estándar proporcionan una std::hash_map
que nunca fue especificado. Si lo usa en su código, no es portátil.
La tendencia moderna es esconder esto en el espacio de nombres std::tr1
para que los programadores sepan que se trata de una extensión.
También tenga en cuenta que muchos definen typedef
o macros que no son genéricos (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 se especifica en la norma. Si haces bit-twiddling y esperas que tenga 32 bits, estarás atornillado a las plataformas de 64 bits incluso sin cambiar tu compilador.
API de la plataforma
Nuestros programas están diseñados para ser compilado, y que a menudo están destinados a interactuar con el ordenador que se ejecutan en:
Necesita encontrar API portátiles multiplataforma o hacer las suyas propias. Verifique algunas bibliotecas en la lista a continuación.
Bibliotecas
bibliotecas más bien escritos son en gran medida portátil, sólo asegúrese de que ellos apoyan:
Buenas bibliotecas implican:
Los otros que hay que revisar ... y que requiere tiempo.
No creo que haya una respuesta perfecta allí. Pero como la portabilidad perfecta no es posible, debe decidir qué compiladores y plataforma desea admitir.
Para la plataforma, debe comenzar con Windows y un sabor Linux. Para los compiladores, elija dos (con Comeau si puede pagarlo).
Las matrices de longitud variable probablemente se admiten porque están en el estándar ISO C 99, no por razones de practicidad. – ninjalj
Muchos compiladores no implementan C99 en absoluto (por ejemplo, MSVC). Las matrices de longitud variable no son C++. –
De hecho, anhelo macros variadas y sin embargo no son C++ :( –
una buena idea es utilizar 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 funciones POSIX, como éste: [1]: http://sourceware.org/pthreads-win32/
Diría que el uso de llamadas al sistema POSIX es exactamente lo contrario del código portátil. En lugar de eso, utilice las bibliotecas de alto nivel como las mencionadas en el otro – Philipp
mantener el código específico de la plataforma independiente de 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
en todas partes, tendrá una pesadilla de mantenimiento.
Luego, compile en 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 compilador se comparten, se detectará el código no portátil antes de que se arraigue profundamente en su diseño.
automatice sus compilaciones, usando algo como Hudson, que se compilará según el cronograma (hora/día/día/en CVS checkin, etc.) y correo electrónico si falla una compilación. Puede usar máquinas virtuales y buidl para, por ejemplo, Windows y Linux en una PC – Mawg
El código independiente del sistema operativo es sorprendentemente difícil de hacer en C++. Considere este ejemplo trivial:
#include <iostream>
int main(int argc, char** argv) {
std::cout << argv[0] << std::endl;
}
Eso es perfectamente válida C++, todavía es no portátil, ya que no aceptará Unicode argumentos de línea de comandos en Windows. La versión correcta para Windows sería:
#include <iostream>
int wmain(int argc, wchar_t** argv) {
std::wcout << argv[0] << std::endl;
}
Por supuesto que es nuevo no portátil, trabajando solamente en Windows y ser no estándar. De hecho, ni siquiera puede escribir una función portátil main()
en C++ sin recurrir a la compilación condicional.
wchar_t no tiene nada que ver con unicode. –
Eso causará problemas en cualquier plataforma. Use 'std :: endl' en su lugar, lo que vacía el búfer y realmente produce algún resultado. No puedo comenzar a contar todas las preguntas Lo he visto en SO, que se reducía a personas que no usaban 'cout'. –
@Alexandre: Correcto, C++ en sí mismo no sabe nada sobre cadenas o Unicode, sino porque W indows usa cadenas UTF-16 y 'wchar_t' siempre es un entero sin signo de 16 bits en Windows (de lo contrario, no se compilaría ningún programa), puede usar' wchar_t' si desea compatibilidad con Unicode en Windows. @Ben: Gracias, lo corregiré. – Philipp
Algunas pautas:
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 es necesario escribir todo el código 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.
Si puede, compile todo su código con al menos dos compiladores diferentes.
Otros dijeron que antes, pero aquí está mi opinión sobre ella:
1) ¿Necesita 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 un 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 continuamente en todas las plataformas seleccionadas. No solo cree en Windows y espere simplemente compilar una versión de Linux 'cuando esté listo'. Compila todas las plataformas a diario y asegúrate de seguir analizándolas en busca de problemas.
Junto con el n. ° 2, generalmente es más fácil pasar de compilar en 2 plataformas a compilar en> 2, que ir del 1 al 2. Agregar una segunda plataforma lo ayudará a encontrar la mayoría de los problemas de portabilidad. – KeithB
+1 para el artículo n. ° 1. C++ es una de las peores elecciones si desea portabilidad, casi cualquier otro idioma, incluso Bash o Visual Basic, es más portátil. – Philipp
A veces estar más cerca de "lo básico" es más portátil que estar drogado, cuando escribo código para el sistema integrado, C sin bibliotecas es el lenguaje más portátil, ¿por qué? porque hay compiladores para cada plataforma y funciona en entornos pequeños, C++ es el siguiente, pero no hay compilador para cada micro, así que volveré a preguntar, depende de "¿A dónde quieres conectarlo?" –
¿Cuáles son las cosas que debo tener en cuenta para escribir código portátil?
+1 para algunos puntos buenos. En realidad hay un MSBuild en Linux, pero probablemente nadie lo use para el código C++: http://www.mono-project.com/Microsoft.Build ... y cuando elijas funciones "estándar", ten en cuenta que es más de un estándar para elegir, y no todas las funciones estándar son portátiles, como aprendí recientemente: http://stackoverflow.com/questions/9896411/why-are-standard-library-function-names-different-between- windows-and-linux – Qwertie
Re artículo 8 Agregaría, no esparce # ifdef a través de su código: tenga una 'plataforma.h' o similar, y ajuste el código dependiente de la plataforma en funciones independientes de la plataforma y concéntrelas. En otras palabras, amplíe su compilador y biblioteca con las características de portabilidad que falta que su código necesita, luego escriba el resto de su código de forma portátil. – Spike0xff
Esto huele como una pregunta de Wiki comunitario. – bta
@bta: ¿Por qué, exactamente? Si alguien dedica 30 minutos a escribir una buena respuesta a esta pregunta, ¿no merecen el representante cuando se sube la apuesta? – jalf
¿Dónde quieres portarlo? hay un mundo de diferencias si planeas portarlo a diferentes sistemas operativos, diferentes arquitecturas, entonces hay una respuesta para cada puerto, por ejemplo, trabajando en 8 o incluso 16 bits pequeños sistemas integrados, debes evitar el uso de cualquiera de las bibliotecas recomendado aquí, entonces, ¿podría ser más específico? –