Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

concatenation de chaines dans des macros

11 réponses
Avatar
Arnaud Meurgues
Bonjour,

J'ai un problème avec gcc 3.4.4. En compilant :

---------------------------------------------------
#define CONCAT(a,b) a##b

static char name[] = CONCAT("un texte" ," en deux bouts");

int main() {}
---------------------------------------------------

Il me sort l'erreur suivante :
[meurgues@precision79]/tmp >g++ gcc.cpp
gcc.cpp:3:1: pasting ""un texte"" and "" en deux bouts"" does not give a
valid preprocessing token

Y a-t-il un moyen simple et élégant de contourner ce problème de gcc
(non, je ne peux pas changer la version) ?

Merci,
--
Arnaud

10 réponses

1 2
Avatar
Fabien LE LEZ
On Tue, 07 Mar 2006 13:29:15 +0100, Arnaud Meurgues
:

#define CONCAT(a,b) a##b

static char name[] = CONCAT("un texte" ," en deux bouts");


Le symbole "##" sert à la concaténation d'indentifiants.

Ce dont tu as besoin ici, c'est la macro suivante :

#define CONCAT(a,b) a b

Avatar
Michel Decima
"Arnaud Meurgues" a écrit dans le
message de news:440d7c78$0$28850$
Bonjour,

J'ai un problème avec gcc 3.4.4. En compilant :

---------------------------------------------------
#define CONCAT(a,b) a##b

static char name[] = CONCAT("un texte" ," en deux bouts");

int main() {}
---------------------------------------------------

Il me sort l'erreur suivante :
[]/tmp >g++ gcc.cpp
gcc.cpp:3:1: pasting ""un texte"" and "" en deux bouts"" does not give a
valid preprocessing token

Y a-t-il un moyen simple et élégant de contourner ce problème de gcc


#define CONCAT(a, b) a b

ca marche dans le cas present, c'est simple, mais je ne sais pas si c'est
elegant (et il doit surement y avoir des contre indications cachees)

(non, je ne peux pas changer la version) ?


avec gcc-4.0.2, j'ai le meme diagnostic pour la macro originale
(par contre xlC-6 l'accepte sans broncher)

Avatar
Arnaud Meurgues
Fabien LE LEZ wrote:

Ce dont tu as besoin ici, c'est la macro suivante :

#define CONCAT(a,b) a b


Tiens, oui. Faut être crétin pour ne pas y avoir pensé.

Merci.

--
Arnaud (crétin)

Avatar
Arnaud Meurgues
Michel Decima wrote:

#define CONCAT(a, b) a b

ca marche dans le cas present, c'est simple, mais je ne sais pas si c'est
elegant (et il doit surement y avoir des contre indications cachees)


Si, si. Ça semble parfaitement élégant.

(par contre xlC-6 l'accepte sans broncher)


C'est ce qui m'a enduit d'erreur...

--
Arnaud

Avatar
Arnaud Meurgues
Arnaud Meurgues wrote:

Si, si. Ça semble parfaitement élégant.


Contrairement à moi qui oublie de remercier.

Merci.

--
Arnaud (crétin et mal poli)

Avatar
kanze
Fabien LE LEZ wrote:
On Tue, 07 Mar 2006 13:29:15 +0100, Arnaud Meurgues
:

#define CONCAT(a,b) a##b

static char name[] = CONCAT("un texte" ," en deux bouts");


Le symbole "##" sert à la concaténation d'indentifiants.


Dans la pratique, c'est rare que le résultat ne doit pas servir
d'identifant. Mais rien ne l'oblige, et les paramètres ne sont
pas toujours des identifiants, par exemple :

#define PASTE2( a, b ) a ## b
#define PASTE( a, b ) PASTE2( a, b )
#define UNIQUENAME( prefix ) PASTE( prefix, __LINE__ )

(On remarque que l'expansion de __LINE__ n'est pas un
identifiant.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Arnaud Meurgues
kanze wrote:

#define CONCAT(a,b) a##b



Dans la pratique, c'est rare que le résultat ne doit pas servir
d'identifant. Mais rien ne l'oblige, et les paramètres ne sont
pas toujours des identifiants, par exemple :

#define PASTE2( a, b ) a ## b
#define PASTE( a, b ) PASTE2( a, b )


À quoi sert de passer par une macro intermédiaire ?
En fait, le code que j'avais et qui ne compilait pas avec gcc (mais avec
tous les autres compilos de mes portages) utilise aussi cette forme à
deux macros.

--
Arnaud



Avatar
James Kanze
Arnaud Meurgues wrote:
kanze wrote:


#define CONCAT(a,b) a##b





Dans la pratique, c'est rare que le résultat ne doit pas
servir d'identifant. Mais rien ne l'oblige, et les paramètres
ne sont pas toujours des identifiants, par exemple :



#define PASTE2( a, b ) a ## b
#define PASTE( a, b ) PASTE2( a, b )



À quoi sert de passer par une macro intermédiaire ?


À le faire marcher:-).

En fait, quand un paramètre sert d'opérand à ## ou à #, on
l'utilise littéralement, sans expansion. Sans la macro
intermédiaire, alors,

#define PASTE2( a, b ) a ## b
#define PASTE( a, b ) PASTE2( a, b )
#define UNIQUENAME( prefix ) PASTE( prefix, __LINE__ )

int UNIQUENAME( aa ) ;
int UNIQUENAME( aa ) ;

devient :

int aa__LINE__ ;
int aa__LINE__ ;

Ce qui n'est pas le but.

Telle que je l'ai écrit, en revanche, __LINE__ est paramètre de
PASTE ; l'expansion a donc lieu dans l'appel à PASTE, parce que
dans PASTE, il n'est pas paramètre d'un ##, et on a le résultat
voulu :

int aa6 ;
int aa7 ;

(Dans le temps, on utilisait de telles techniques pour des
variables locales des fonctions « pseudo-inline », faites à base
des macros.)

En fait, le code que j'avais et qui ne compilait pas avec gcc
(mais avec tous les autres compilos de mes portages) utilise
aussi cette forme à deux macros.


C'est un idiome devenu classique.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34




Avatar
Arnaud Meurgues
James Kanze wrote:

En fait, quand un paramètre sert d'opérand à ## ou à #, on
l'utilise littéralement, sans expansion.


Ok. Bizarrement, cet idiome était utilisé alors qu'il ne servait qu'à
concaténer des chaînes de caractères.

Et sinon, entre gcc qui génère une erreur et Comeau qui accepte sans
broncher, lequel a raison ?

--
Arnaud

Avatar
Jean-Marc Bourguet
Arnaud Meurgues writes:

James Kanze wrote:

En fait, quand un paramètre sert d'opérand à ## ou à #, on
l'utilise littéralement, sans expansion.


Ok. Bizarrement, cet idiome était utilisé alors qu'il ne servait qu'à
concaténer des chaînes de caractères.

Et sinon, entre gcc qui génère une erreur et Comeau qui accepte sans
broncher, lequel a raison ?


Le comportement est explicitement indefini. (Voir 16.3.3/3)

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


1 2