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) ?
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
#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)
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
Fabien LE LEZ wrote:
On Tue, 07 Mar 2006 13:29:15 +0100, Arnaud Meurgues
<news.arnaud@meurgues.non.fr.invalid>:
#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
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
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
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.
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
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
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 kanze.james@neuf.fr
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
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
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
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 ?
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
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
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
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