¿Cuándo son beneficiosas las macros de C++? [closed]

5 minutos de lectura

los C preprocesador es temido y rechazado justificadamente por la comunidad de C++. Las funciones, constantes y plantillas en línea suelen ser una alternativa más segura y superior a un #define.

La siguiente macro:

#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)  

no es en modo alguno superior a la caja fuerte de tipo:

inline bool succeeded(int hr) { return hr >= 0; }

Pero las macros tienen su lugar, enumere los usos que encuentra para las macros que hipocresía prescindir del preprocesador.

Coloque cada caso de uso en una respuesta separada para que pueda votarse y, si sabe cómo lograr una de las respuestas sin el preprocesador, indique cómo en los comentarios de esa respuesta.

  • Una vez tomé una aplicación C++ llena de macros que tardó 45 minutos en compilarse, reemplacé las macros con funciones en línea y reduje la compilación a menos de 15 minutos.

    – endian

    23 de octubre de 2008 a las 7:37

  • Afirmación estática

    – Özgür

    8 de marzo de 2009 a las 0:42

  • El hilo trata sobre contextos en los que las macros son beneficiosas, no contextos en los que no son óptimas.

    – subrayado_d

    25 mayo 2017 a las 21:46

  • @Özgür ¿Qué pretendes decir?

    – Juan

    24 de septiembre de 2021 a las 2:49

Los métodos siempre deben ser código completo y compilable; las macros pueden ser fragmentos de código. Por lo tanto, puede definir una macro foreach:

#define foreach(list, index) for(index = 0; index < list.size(); index++)

Y úsalo así:

foreach(cookies, i)
    printf("Cookie: %s", cookies[i]);

Desde C++11, esto es reemplazado por el bucle for basado en rango.

  • +1 Si está utilizando una sintaxis de iterador ridículamente compleja, escribir una macro de estilo foreach puede hacer que su código sea mucho más fácil de leer y mantener. Lo he hecho, funciona.

    – posfuturista

    25 de octubre de 2008 a las 21:01

  • La mayoría de los comentarios son completamente irrelevantes hasta el punto de que las macros pueden ser fragmentos de código en lugar de código completo. Pero gracias por la quisquillosidad.

    – jdmichal

    12 de noviembre de 2008 a las 20:15

  • Esto es C, no C++. Si está haciendo C++, debería usar iteradores y std::for_each.

    – Chris

    11 de junio de 2009 a las 19:19

  • No estoy de acuerdo, Chris. antes de la lambda, for_each fue algo desagradable, porque el código por el que se ejecutaba cada elemento no era local para el punto de llamada. foreach(y recomiendo encarecidamente BOOST_FOREACH en lugar de una solución hecha a mano) mantenga el código cerca del sitio de iteración, haciéndolo más legible. Dicho esto, una vez que se implemente la lambda, for_each podría ser una vez más el camino a seguir.

    – GManNickG

    18 de agosto de 2009 a las 23:50

  • Y vale la pena señalar que BOOST_FOREACH es en sí mismo una macro (pero muy bien pensada)

    – Tyler McHenry

    18 de agosto de 2009 a las 23:56

  • La mayoría de los compiladores admiten #pragma once en estos días, así que dudo que los guardias sean realmente necesarios

    – 1800 INFORMACIÓN

    18 de septiembre de 2008 a las 20:10

  • Lo son si está escribiendo para todos los compiladores en lugar de solo para la mayoría 😉

    –Steve Jessop

    18 de septiembre de 2008 a las 20:13

  • Entonces, en lugar de la funcionalidad de preprocesador estándar portátil, ¿recomienda usar una extensión de preprocesador para evitar usar el preprocesador? Me parece algo ridículo.

    –Logan Capaldo

    8 de marzo de 2009 a las 0:49

  • #pragma once se rompe en muchos sistemas de compilación comunes.

    – Ruta Millas

    3 de junio de 2014 a las 3:58

  • Hay una solución para eso que no requiere macros: void handleExceptions(){ try { throw } catch (::mylib::exception& e) {....} catch (::std::exception& e) {...} ... }. Y en el lado de la función: void Foo(){ try {::mylib::Foo() } catch (...) {handleExceptions(); } }

    – Mike MB

    2 de julio de 2016 a las 23:59


Principalmente:

  1. Incluir guardias
  2. compilación condicional
  3. Informes (macros predefinidos como __LINE__ y __FILE__)
  4. (raramente) Duplicación de patrones de código repetitivos.
  5. En el código de su competidor.

  • Buscando ayuda sobre cómo realizar el número 5. ¿Me puede guiar hacia una solución?

    – Máx.

    14 de febrero de 2020 a las 13:49

  • @David Thornley ¿Podría mostrarme un ejemplo de “compilación condicional”?

    – Juan

    24 de septiembre de 2021 a las 3:05

Dentro de la compilación condicional, para superar problemas de diferencias entre compiladores:

#ifdef WE_ARE_ON_WIN32
#define close(parm1)            _close (parm1)
#define rmdir(parm1)            _rmdir (parm1)
#define mkdir(parm1, parm2)     _mkdir (parm1)
#define access(parm1, parm2)    _access(parm1, parm2)
#define create(parm1, parm2)    _creat (parm1, parm2)
#define unlink(parm1)           _unlink(parm1)
#endif

  • Buscando ayuda sobre cómo realizar el número 5. ¿Me puede guiar hacia una solución?

    – Máx.

    14 de febrero de 2020 a las 13:49

  • @David Thornley ¿Podría mostrarme un ejemplo de “compilación condicional”?

    – Juan

    24 de septiembre de 2021 a las 3:05

Cuando desea hacer una cadena a partir de una expresión, el mejor ejemplo para esto es assert (#x convierte el valor de x a una cadena).

#define ASSERT_THROW(condition) \
if (!(condition)) \
     throw std::exception(#condition " is false");

  • Solo un detalle, pero personalmente dejaría el punto y coma fuera.

    – Michael Myers

    18 de septiembre de 2008 a las 21:05

  • Estoy de acuerdo, de hecho, lo pondría en un do {} while (false) (para evitar el secuestro) pero quería mantenerlo simple.

    – Motti

    5 de octubre de 2008 a las 18:24

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad