Outils pour utilisateurs

Outils du site


lang:c:preprocesseur

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
lang:c:preprocesseur [2016/07/04 18:48] – ↷ Page déplacée de c:preprocesseur à lang:c:preprocesseur rootlang:c:preprocesseur [2024/04/09 15:21] (Version actuelle) – Ajout de "Forcer le ; après une macro" root
Ligne 1: Ligne 1:
-=====Convertir un nombre en chaîne de caractères===== +===Convertir un nombre en chaîne de caractères=== 
-[[http://stackoverflow.com/questions/5459868/c-preprocessor-concatenate-int-to-string|Source]]{{:c:preprocesseur:c_preprocessor_concatenate_int_to_string_-_stack_overflow.maff|Archive}}+ 
 +{{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===
  
 <code c> <code c>
-#define STR_HELPER(x#x +#define SOME_BIG_MACRO(input)\ 
-#define STR(xSTR_HELPER(x)+  SOME_FUNCTION_CALL()  /* this does... */ \ 
 +  SOME_OTHER_FUNCTION_CALL()
 </code> </code>
  
-Exemple d'utilisation :+===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 
 <code c> <code c>
-#define GCCVERSION STR(__GNUC__"." STR(__GNUC_MINOR__"." STR(__GNUC_PATCHLEVEL__)+#define SKIP_SPACES(p, limit \ 
 +{ char *lim = (limit);         \ 
 +  while (p < lim{            \ 
 +    if (*p++ != ' ') {         \ 
 +      p--; break; }}} 
 + 
 +if (*p != 0) 
 +  SKIP_SPACES (p, lim); 
 +else
 </code> </code>
 +
 +Problème : il y a un '';'' après un ''}''.
 +
 +Solution : ''do{} while (0);''.
 +
 +<code c>
 +#define SKIP_SPACES(p, limit)     \
 +do { char *lim = (limit);         \
 +     while (p < lim) {            \
 +       if (*p++ != ' ') {         \
 +         p--; break; }}}          \
 +while (0)
 +</code>
 +
 +[[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 :
 +
 +<code c>
 +#define MACRO() \
 +void foo(){}
 +</code>
 +
 +Solution : ''static_assert''.
 +
 +<code c>
 +#ifdef __cplusplus
 +#include <cassert>
 +#else
 +#include <assert.h>
 +#endif
 +
 +#define MACRO() \
 +void foo(){} \
 +static_assert(true, "")
 +
 +MACRO();
 +</code>
 +
 +[[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.
 +
 +<code cpp>
 +#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
 +</code>
 +
 +[[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 :
 +
 +<code c>
 +#if defined(_WIN32)
 +#elif __APPLE__
 +#elif __ANDROID__
 +#elif __linux__
 +#else
 +#   error "Unknown compiler"
 +#endif
 +</code>
 +
 +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.
lang/c/preprocesseur.1467650889.txt.gz · Dernière modification : 2016/07/04 18:48 de root