Secciones

miércoles, 27 de enero de 2016

Macros predefinidas oficiales para C/C++ que te pueden salvar la vida.

Si programais en C/C++, deberíais saber que existen sintaxis para tratar partes del código antes de ser usado, esta herramienta es llamada el preprocesador de C/C++ y es el primer programa invocado por el compilador.

Sintaxis:
  • #include "filename.h", se utiliza para hacer referencias a cabeceras de código, que contienen la descripción de variables y funciones a usar. Ya sea de la propia librería o de otra.
  • #define __VAR__ ARG_OPTIONAL, se utiliza para crear una variable, puede verse si existe con #ifdef o #if (defined(__VAR__)), o ser sustituido por el ARG_OPTIONAL
  • #if, #elif, #else, se utiliza como un if normal
  • #ifdef, #ifndef,#elif, #else, se utiliza para comprobar si se ha definido cierta variable
  • defined(__VAR__), devuelve 1 si existe un define previo de la __VAR__
  • #warning "message", se utiliza para informar de errores SIN parar la compilación, visual studio no la soporta, puede usar #pragma "message" como alternativa.
  • #error "message", se utiliza para informar de errores Y parar la compilación

Macros predefinidas:

Viene bien tener la referencia a las macros de GCC y de MVS. No todas tienen porque ser soportadas por otros compiladores, que o bien las ignorarán, o bien fallarán y tendrás que anidarlas en el típico #ifndef(_MSC_VER). Gracias a esto puedes controlar el tipo y la versión del compilador, para alertar de funcionalidades o fallos y hacer la vida más fácil a otros desarrolladores que usen tu código.


¿Realmente son tan importantes?

Mirar siempre los includes que usas es realmente importante para entender que cosas está teniendo en cuenta el código antes de compilarlo. De esta forma se puede diferenciar distintas plataformas, arquitecturas, tamaños de vectores y datos en función de la capacidad de la máquina para la que se compila.

Me encontré este problema por olvidarme al pasar de un proyecto a otro código preprocesado, al no estar definidas ciertas cosas y usar unos no oficiales confundía código de Android y Ipad, con efectos desastrosos en la imagen. Obviamente cuando se ve azul en lugar de correcto sabes que algo va mal, pero es cuestión de habilidad y experiencia encontrar rápidamente la fuente del error. Mi fallo fué omitir en todo el proyecto, en dispositivos __APPLE__ el include de C con los defines:
#include "TargetConditionals.h"
Este include de apple define muchas variables de preprocesado muy útiles a la hora de distinguir iOS de MAC y otras plataformas.

Otros ejemplos:

- Gracias a ayuda de ciertos usuarios en StackOverFlow pude desarrollar un logger multiplataforma para ofrecer información útil ordenada en distintos dispositivos. No es thread-safe.

- Básico, si usas mi logger.h puedes usar este código para printear info en cualquier cpp:

#include "logger.h"
#define LOG_TAG "MyCpp"


#pragma "Let's check our arch"

#ifdef __linux__
    // All linux arch
#elif _WIN32
    // Windows 32 and 64
#elif __APPLE__
#  include "TargetConditionals.h"
#  ifdef TARGET_OS_IOS
    // including iPhone and iPad
#  elif TARGET_IPHONE_SIMULATOR
    // iOS Simulator
#  elif TARGET_OS_MAC
    // Other kinds of Mac OS
#  else
     // Unsupported platform
#  endif
#elif __ANDROID__
    // Android all versions
#else
    // Unsupported architecture
#    error "I don't know the arch"
#endif

#if defined(LOG_TAG)
    #pragma "Log tag is defined in this cpp"
#endif

No hay comentarios:

Publicar un comentario