Macro stringification et concatenation

Le problème exposé dans ce sujet a été résolu.

Bonjour,

J'ai un petit soucis avec les macros.

Pour mon projet j'ai quelque macro du style

1
2
3
#define TEST_ASSERT(p_condition) Test::Assert(p_expected, 0, __FUNCTION__, __LINE__, __FILE__)
#define TEST_ASSERT_EQUAL(p_expected, p_actual) Test::Assert(p_expected, p_actual, __FUNCTION__, __LINE__, __FILE__)
/* Test::Assert est un template que l'on peut spécialiser, et qui fait en gros if(p_exepected != p_actual) error() */

Quand l'assert catch, j'ai une trace (d'où la réimplantation, je ne crash pas l'exe).

1
[ERROR | myFunction < 23 < MyFile.hpp ] Assert fail! 

Mon soucis : j'aimerais arriver à afficher les valeurs passés en paramètres de ma macro. Avec un seul paramètre c'est très simple :

1
2
3
4
//avant
#define TEST_ASSERT(p_condition) Test::Assert(p_expected, 0, __FUNCTION__, __LINE__, __FILE__)
//après
#define TEST_ASSERT(p_condition) Test::Assert(p_expected, 0, #p_condition,__FUNCTION__, __LINE__, __FILE__)

Mais, que deviens ceci ?

1
2
3
4
//avant
#define TEST_ASSERT_EQUAL(p_expected, p_actual) Test::Assert(p_expected, p_actual, __FUNCTION__, __LINE__, __FILE__)
//après (ne fonctionne pas)
#define TEST_ASSERT_EQUAL(p_expected, p_actual) Test::Assert(p_expected, p_actual, #p_exepected ## #p_actual ,__FUNCTION__, __LINE__, __FILE__)

sous clang :

1
error: pasting formed '"foo""bar"', an invalid preprocessing token

sous gcc

1
error: pasting ""foo"" and ""bar"" does not give a valid preprocessing token

(cela ne fonctionne pas également avec autre chose qu'une chaine, comme un variable par exemple).

J'ai dû louper un truc sur les macros, les pages comme la doc gcc ne m'ont pas beaucoup aidé…

oui j'utilise des macro en c++, c'est mal toussa toussa, je suis au courant ;-)

D'avance merci.

Passe par une macro sur 2 étages :

1
2
3
4
5
6
7
8
#define TEST_ASSERT_EQUAL_s(tok) Test::Assert(p_expected, p_actual, #tok ,__FUNCTION__, __LINE__, __FILE__)
#define TEST_ASSERT_EQUAL(p_expected, p_actual) TEST_ASSERT_EQUAL_s(p_expected##p_actual)

int main(int argc, char *argv[])
{
    TEST_ASSERT_EQUAL(foo,bar)
    return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
g++ -E d.cpp
# 1 "d.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "d.cpp"
int main(int argc, char *argv[])
{
    Test::Assert(p_expected, p_actual, "foobar" ,__FUNCTION__, 6, "d.cpp")
    return 0;
}

Sinon, pourquoi ne pas utiliser un framework de test ?

Edit : ca m'apprendra à pas suivre les liens des gens.

+1 -0

Merci pour vos réponse. Je n'utilise pas de framework de test parce que je suis sur un embarqué. Généralement les frameworks viennent avec tout un tas de dépendances, j'ai été infiniment plus vite à développer ce truc de test simpliste qu'à essayer d'adapter un machin qui marchera une fois sur 2.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte