Affichage de la valeur de constantes a la compilation

Résolu
ToutEnMasm
Messages postés
590
Date d'inscription
jeudi 28 novembre 2002
Statut
Membre
Dernière intervention
18 septembre 2021
- Modifié le 15 août 2020 à 21:58
cptpingu
Messages postés
3834
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
20 octobre 2021
- 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
590
Date d'inscription
jeudi 28 novembre 2002
Statut
Membre
Dernière intervention
18 septembre 2021
3
24 août 2020 à 20:28
Vu l'absence de réponse,cela ne semble pas possible.


--
0
Whismeril
Messages postés
17483
Date d'inscription
mardi 11 mars 2003
Statut
Modérateur
Dernière intervention
4 juillet 2022
600
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
590
Date d'inscription
jeudi 28 novembre 2002
Statut
Membre
Dernière intervention
18 septembre 2021
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
3834
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
20 octobre 2021
124
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
3834
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
20 octobre 2021
124
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
3834
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
20 octobre 2021
124
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
590
Date d'inscription
jeudi 28 novembre 2002
Statut
Membre
Dernière intervention
18 septembre 2021
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
3834
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
20 octobre 2021
124
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