Affichage de la valeur de constantes a la compilation

Résolu
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 - Modifié le 15 août 2020 à 21:58
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 14 févr. 2021 à 16:31
Bonjour,
Pour la mise au point de macros ,on a souvent besoin d'afficher des résultats intermédiaires
a la compilation.
exemple :
#define FCC(ch4) ((((DWORD)(ch4) & 0xFF) << 24) |     \
                  (((DWORD)(ch4) & 0xFF00) << 8) |    \
                  (((DWORD)(ch4) & 0xFF0000) >> 8) |  \
                  (((DWORD)(ch4) & 0xFF000000) >> 24))

en pseudo code:
afficher_valeur (FCC(555))                // affichage dans fenêtre compilation

8 réponses

ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
24 août 2020 à 20:28
Vu l'absence de réponse,cela ne semble pas possible.


--
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
25 août 2020 à 08:56
Bonjour, ne tire pas de conclusion hâtive.
L'absence de réponse est d'abord due au peu de fréquentation du site, encore moindre au moi d'aout.
0
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
Modifié le 12 févr. 2021 à 23:33
J'ai trouvé "#pragma message" semblant convnir.
#include <windows.h>
#include <iostream>

#define STRING2(x) #x
#define STRING(x) STRING2(x)


#define FCC(ch4) ((((DWORD)(ch4) & 0xFF) << 24) |     \
                  (((DWORD)(ch4) & 0xFF00) << 8) |    \
                  (((DWORD)(ch4) & 0xFF0000) >> 8) |  \
                  (((DWORD)(ch4) & 0xFF000000) >> 24));

int main()
{

    const int rien = FCC(555);
     #pragma message (__FILE__ "[" STRING(__LINE__) "]: test") 
    #pragma message(STRING(FCC(555)))
    #pragma message(STRING(rien))


affichage:
essai.cpp[22]: test
((((DWORD)(555) & 0xFF) << 24) | (((DWORD)(555) & 0xFF00) << 8) | (((DWORD)(555) & 0xFF0000) >> 8) | (((DWORD)(555) & 0xFF000000) >> 24));
rien
rien devrait apparaitre comme un chiffre ,comment faire ?
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié le 13 févr. 2021 à 21:52
Bonjour !

Tu ne peux pas afficher la valeur d'une variable calculée à l'exécution, lors de la compilation. Soit tu affiches la valeur du résultat de FCC(), soit tu mets ce résultat en tant qu'alias dans un define.

Exemple:
#include <iostream>

// DWORD not exist on Unix, let's alias it :). Remove this line on Windows.
#define DWORD unsigned long int

#define STRING2(x) #x
#define STRING(x) STRING2(x)

#define FCC(ch4) ((((DWORD)(ch4) & 0xFF) << 24) |       \
                  (((DWORD)(ch4) & 0xFF00) << 8) |      \
                  (((DWORD)(ch4) & 0xFF0000) >> 8) |    \
                  (((DWORD)(ch4) & 0xFF000000) >> 24));

#define RIEN FCC(555)

int main()
{
  const int rien = RIEN;

#pragma message (__FILE__ "[" STRING(__LINE__) "]: test")
#pragma message(STRING(FCC(555)))
#pragma message(STRING(RIEN))
#pragma message(STRING(rien))

  std::cout << rien << std::endl;
  return 0;
}


Si tu veux le résultat, et non l'expression, ce n'est pas possible sans exécuter le code tout simplement. Le pré-processeur manipule du texte, il n'interprète, ni ne calcul rien.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié le 13 févr. 2021 à 21:50
Bon, j'ai trouvé une solution "sale", et qui ne fonctionne pas partout.
Ça consiste à détourner un warning particulier, pour qu'il affiche le résultat d'un template.
Ça fonctionne sous clang et g++, je ne sais pas si ça fonctionnera avec Visual Studio :(.

Voici le code:
#include <iostream>

#define DWORD unsigned long int

template <DWORD N>
struct MSG
{
  MSG()
  {
    int i;
    int d = i; // Provoque un warning uninitialized volontairement.
  }
};

#define FCC(ch4) ((((DWORD)(ch4)&0xFF) << 24) |    \
                  (((DWORD)(ch4)&0xFF00) << 8) |   \
                  (((DWORD)(ch4)&0xFF0000) >> 8) | \
                  (((DWORD)(ch4)&0xFF000000) >> 24))

#define MESSAGE(expr) MSG<expr>()

int main()
{
  MESSAGE(4 + 5);
  MESSAGE(FCC(555));

  return 0;
}


Il faut que la compilation soit lancée avec des options particulières:
g++ masm.cc -std=c++11 -Wuninitialized


Voici le résultat chez moi (inesthétique, mais fonctionnel):
masm.cc:11:13: warning: variable 'i' is uninitialized when used here [-Wuninitialized]
int d = i;
^
masm.cc:24:3: note: in instantiation of member function 'MSG<9>::MSG' requested here
MESSAGE(4 + 5);
^
masm.cc:20:23: note: expanded from macro 'MESSAGE'
#define MESSAGE(expr) MSG<expr>()
^
masm.cc:10:10: note: initialize the variable 'i' to silence this warning
int i;
^
= 0
masm.cc:11:13: warning: variable 'i' is uninitialized when used here [-Wuninitialized]
int d = i;
^
masm.cc:25:3: note: in instantiation of member function 'MSG<721551360>::MSG' requested here
MESSAGE(FCC(555));
^
masm.cc:20:23: note: expanded from macro 'MESSAGE'
#define MESSAGE(expr) MSG<expr>()
^
masm.cc:10:10: note: initialize the variable 'i' to silence this warning
int i;
^
= 0
2 warnings generated.


Ça reste très bancale. Pas sur que ce soit possible "proprement".
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié le 13 févr. 2021 à 22:31
J'ai une solution un petit peu moins "moche", et qui pourrait fonctionner sur un compilateur qui supporte le "static_assert". Le défaut par contre, c'est que c'est une erreur et non un warning, et donc la compilation s'arrête :(.

Voici le code:
#include <iostream>

#define DWORD unsigned long int

#define FCC(ch4) ((((DWORD)(ch4)&0xFF) << 24) |    \
                  (((DWORD)(ch4)&0xFF00) << 8) |   \
                  (((DWORD)(ch4)&0xFF0000) >> 8) | \
                  (((DWORD)(ch4)&0xFF000000) >> 24))

template <DWORD N>
struct MSG
{
  static const bool val = false;
};

#define MESSAGE(expr) static_assert(MSG<expr>::val, #expr)

int main()
{
  MESSAGE(4 + 5);
  MESSAGE(FCC(555));
}


Chez moi, j'ai ceci:
masm.cc:20:3: error: static_assert failed due to requirement 'MSG<7>::val' "3 + 4"
MESSAGE(3 + 4);
^~~~~~~~~~~~~~
masm.cc:16:23: note: expanded from macro 'MESSAGE'
#define MESSAGE(expr) static_assert(MSG<expr>::val, #expr)
^ ~~~~~~~~~~~~~~
masm.cc:21:3: error: static_assert failed due to requirement 'MSG<721551360>::val' "FCC(555)"
MESSAGE(FCC(555));
^~~~~~~~~~~~~~~~~
masm.cc:16:23: note: expanded from macro 'MESSAGE'
#define MESSAGE(expr) static_assert(MSG<expr>::val, #expr)
^ ~~~~~~~~~~~~~~
2 errors generated.
0
ToutEnMasm Messages postés 587 Date d'inscription jeudi 28 novembre 2002 Statut Membre Dernière intervention 13 décembre 2022 3
14 févr. 2021 à 16:09
Bonjour,
Merci pour les efforts.
Il y a quelque chose que je ne comprends pas trop.

#define STRING2(x) #x
#define STRING(x) STRING2(x)

Vu de loin ,ça ressemble a quelque chose de magique ,d'autant plus que j'ai vu les mêmes définitions avec un autre nom et une même utilisation.
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié le 14 févr. 2021 à 16:31
Les macro C ne sont pas vraiment récursives. Elles "expandent" ce qu'elles trouvent. Or, si tu veux forcer une sous macro à être expand, il faut repasser dessus.
Quelques (succintes) explications ici:
https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms#recursion

Un exemple:
#include <iostream>

#define _STR(x) #x
#define STR(x) _STR(x)
#define ADD(a, b) a + b

int main()
{
  std::cout << _STR(ADD(3, 4)) << std::endl; // ADD(3, 4)
  std::cout << STR(ADD(3, 4)) << std::endl;  // 3 + 4
}


Si on applique "#" sur ADD(3, 4), il nous affichera, littéralement "ADD(3, 4)".
Il faut lui dire d'interpréter la macro ADD, et pour ça on le fait passer par une étape "inutile" juste pour forcer le préprocesseur à interpréter ce qui est contenu.
0
Rejoignez-nous