===Convertir un nombre en chaîne de caractères===
{{gh>https://github.com/bansan85/wiki_le_garrec_fr/blob/master/cpp/preprocessor/str_helper.h}}
Exemple d'utilisation :
{{gh>https://github.com/bansan85/wiki_le_garrec_fr/blob/master/cpp/preprocessor/str_helper.cpp}}
Rendu :
{{gh>https://github.com/bansan85/wiki_le_garrec_fr_travis/blob/master/cpp/preprocessor/str_helper.cpp.i}}
[[http://stackoverflow.com/questions/5459868/c-preprocessor-concatenate-int-to-string|C Preprocessor_ concatenate int to string - Stack Overflow]] {{ :lang:c:preprocesseur:concatenate_int_to_string_using_c_preprocessor_-_stack_overflow_2019-10-17_19_34_41_.html |Archive du 28/03/2011 le 17/10/2019}}
===Ecrire un commentaire dans une macro multi lignes===
#define SOME_BIG_MACRO(input)\
SOME_FUNCTION_CALL() /* this does... */ \
SOME_OTHER_FUNCTION_CALL()
===Forcer le ; après une macro===
Chaque ligne de code doit se terminer par un '';''.
Cela peut poser problème avec certaines macros.
* Deux lignes de code
#define SKIP_SPACES(p, limit) \
{ char *lim = (limit); \
while (p < lim) { \
if (*p++ != ' ') { \
p--; break; }}}
if (*p != 0)
SKIP_SPACES (p, lim);
else
Problème : il y a un '';'' après un ''}''.
Solution : ''do{} while (0);''.
#define SKIP_SPACES(p, limit) \
do { char *lim = (limit); \
while (p < lim) { \
if (*p++ != ' ') { \
p--; break; }}} \
while (0)
[[https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html|Swallowing the Semicolon]] {{ :lang:c:preprocesseur:swallowing_the_semicolon_the_c_preprocessor_4_9_2024_3_14_34_pm_.html |Archive du 2002 le 09/04/2024}}
* Une fonction complète
Problème :
#define MACRO() \
void foo(){}
Solution : ''static_assert''.
#ifdef __cplusplus
#include
#else
#include
#endif
#define MACRO() \
void foo(){} \
static_assert(true, "")
MACRO();
[[https://stackoverflow.com/questions/35530850/how-to-require-a-semicolon-after-a-macro|How to require a semicolon after a macro]] {{ :lang:c:preprocesseur:c_-_how_to_require_a_semicolon_after_a_macro_-_stack_overflow_4_9_2024_3_18_23_pm_.html |Archive du 21/02/2016 le 09/04/2024}}
===Détection du compilateur===
Note : sous ''clang'' et le compilateur d'Intel, ''%%__GNUC__%%'' est défini.
#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-truncation"
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdocumentation"
#endif
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4242)
#endif
...
#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
#pragma GCC diagnostic pop
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif
[[https://stackoverflow.com/questions/38499462/how-to-tell-clang-to-stop-pretending-to-be-other-compilers|How to tell Clang to stop pretending to be other compilers?]] {{ :lang:c:preprocesseur:gcc_-_how_to_tell_clang_to_stop_pretending_to_be_other_compilers_-_stack_overflow_14_10_2022_14_17_09_.html |Archive du 21/07/2016 le 14/10/2022}}
===Détection de l'OS===
* Windows : ''_WIN32'',
* Windows 64 bit : ''_WIN64'',
* Linux : ''%%__linux__%%'',
* Android : ''%%__ANDROID__%%''.
[[https://github.com/cpredef/predef/blob/master/OperatingSystems.md|Operating Systems]] {{ :lang:c:preprocesseur:predef_operatingsystems.md_at_master_cpredef_predef_github_23_01_2023_16_48_59_.html |Archive du 18/10/2022 le 23/01/2023}}
Cas courant :
#if defined(_WIN32)
#elif __APPLE__
#elif __ANDROID__
#elif __linux__
#else
# error "Unknown compiler"
#endif
Note : Apple définit également ''%%__linux__%%''. Il faut donc vérifier en premier ''%%defined(__APPLE__)%%'' si on veut faire une distinction entre les deux.
[[https://stackoverflow.com/questions/142508/how-do-i-check-os-with-a-preprocessor-directive|How do I check OS with a preprocessor directive?]] {{ :lang:c:preprocesseur:c_-_how_do_i_check_os_with_a_preprocessor_directive_-_stack_overflow_23_01_2023_12_05_01_.html |Archive du 26/09/2008 le 23/01/2023}}
===Risque du coding style (espace avant parenthèse)===
Si on souhaite faire passer des arguments à la macro, il est nécessaire que la parenthèse touche le nom de la macro. Sinon, le préprocesseur interprétera la parenthèse comme le début du remplacement.
Exemple :
{{gh>https://github.com/bansan85/wiki_le_garrec_fr/blob/master/cpp/preprocessor/macro_and_spaces.cpp}}
Rendu :
{{gh>https://github.com/bansan85/wiki_le_garrec_fr_travis/blob/master/cpp/preprocessor/macro_and_spaces.cpp.i}}
Heureusement, l'erreur est presque toujours détectée à la compilation mais elle peut être difficilement trouvée. C'est pour cette raison que je déconseille l'utilisation d'un espace avant les parenthèses comme règle de codage.