Le préprocesseur GNU marche comme prévu par le standard C, ce qui n'est pas vraiment le cas de celui de M$VC. Un token préprocesseur valide est soit:
* un opérateur
* un identifiant (lettre + suite de chiffres et de lettres)
* "nombre du préprocesseur" (chiffre + suite de chiffres et de lettres, et quelques cas particuliers avec ., e-, d-, e+ et d+). La définition est plus générale que celle d'un "nombre du compilateur" pour pouvoir les utiliser comme des morceaux d'identifiants dans les collages. Si à la fin, on n'obtient pas un "nombre du compilateur" ou un identifiant, on aura une erreur en compilant.
* une directive ('#' + suite de chiffres et de lettres)
(Dans tout ceci, '_' est considéré comme une lettre.)
Tout le reste n'est pas un token préprocesseur valide, et le préprocesseur n'est pas obligé d'accepter ça comme un token. Or, ## est censé produire un token, d'où ton erreur. Le ## est totalement inutile s'il s'agit de 2 tokens différents, donc vire-le.
Tu te compliques vachement la vie:
#define TOTO(a, b, c) (a c b)
suffit.
Moi, je trouve contre-intuitif et stupide de vouloir concaténér 2 tokens qui ne forment pas un token préprocesseur valide.
Quand on préprocesse et compile en même temps, les tokens peuvent être passés directement au parser, ce qui accélère la compilation. C'est ce qui, à ma connaissance, va se passer de plus en plus avec GCC. C'est pour ça que tu as ce warning, qui est désormais une erreur depuis GCC 3.3.
Tu coupes tes fichiers source en plusieurs suivant chacun une convention, et tu utilises la méthode des #ifdef.
Ou alors, plus sale, tu réinclus le header à chaque fois que la convention a changé.
Ou encore, tu utilises 2 ou 3 macros, un avec chaque convention.