web-dev-qa-db-fra.com

Comment définir un littéral de chaîne en ligne de commande gcc?

Dans la ligne de commande gcc, je veux définir une chaîne telle que -Dname=Mary, Puis dans le code source je veux que printf("%s", name); imprime Mary.
Comment pourrais-je le faire?

65
richard

Deux options. Tout d'abord, échappez aux guillemets pour que le Shell ne les mange pas:

gcc -Dname=\"Mary\"

Ou, si vous voulez vraiment -Dname = Mary, vous pouvez le forcer, bien que ce soit un peu hacky.

#include <stdio.h>

#define STRINGIZE(x) #x
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)


int main(int argc, char *argv[])
{
    printf("%s", STRINGIZE_VALUE_OF(name));
}

Notez que STRINGIZE_VALUE_OF se fera un plaisir d'évaluer jusqu'à la définition finale d'une macro.

82

pour éviter que le shell "mange" les guillemets et autres caractères, vous pouvez essayer des guillemets simples, comme ceci:

gcc -o test test.cpp -DNAME='"Mary"'

De cette façon, vous avez un contrôle total sur ce qui est défini (guillemets, espaces, caractères spéciaux et tout).

24
Johann

Le moyen le plus portable que j'ai trouvé jusqu'à présent est d'utiliser \"Mary\" - cela fonctionnera non seulement avec gcc mais avec n'importe quel autre compilateur C. Par exemple, si vous essayez d'utiliser /Dname='"Mary"' avec le compilateur Microsoft, il s'arrêtera avec une erreur, mais /Dname=\"Mary\" marchera.

6
psihodelia

Dans Ubuntu, j'utilisais un alias qui définit CFLAGS, et CFLAGS incluait une macro qui définit une chaîne, puis j'utilise CFLAGS dans un Makefile. J'ai dû échapper aux doubles guillemets et aussi aux caractères \. Cela ressemblait à ceci:

CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
5
Samuel

Voici un exemple simple:

#include <stdio.h>
#define A B+20 
#define B 10
int main()
{
    #ifdef __DEBUG__
        printf("__DEBUG__ DEFINED\n");
        printf("%d\n",A);
    #else
        printf("__DEBUG__ not defined\n");
        printf("%d\n",B);
    #endif
    return 0;
}

Si je compile:

$gcc test.c

Sortie:

__DEBUG__ not defined
10

Si je compile:

$gcc -D __DEBUG__ test.c

Sortie:

__DEBUG__ defined
30
1
Hossein

FYI: Apparemment, même différentes versions de la même chaîne d'outils sur le même système peuvent agir différemment à cet égard ... (Comme dans, il semblerait que cela être un problème qui passe par Shell, mais apparemment, il ne se limite pas au Shell).

Ici, nous avons xc32-gcc 4.8.3 vs. (avr-) gcc 4.7.2 (et plusieurs autres) utilisant le même makefile et main.c , la seule différence étant 'make CC=xc32-gcc', etc.

CFLAGS += -D'THING="$(THINGDIR)/thing.h"' est utilisée sur de nombreuses versions de gcc (et bash) depuis plusieurs années.

Afin de rendre cela compatible avec xc32-gcc (et à la lumière d'un autre commentaire affirmant que\"est plus portable que '"), il fallait faire ce qui suit:

CFLAGS += -DTHING=\"$(THINGDIR)/thing.h\"

ifeq "$(CC)" "xc32-gcc"
CFLAGS := $(subst \",\\\",$(CFLAGS))
endif

rendre les choses vraiment déroutantes en découvrant ceci: apparemment un -D non cité avec un // résulte en un #define avec un commentaire à la fin ... par exemple.

THINGDIR=/thingDir/ -> #define /thingDir//thing.h -> #define /thingDir

(Merci pour l'aide de la réponse s ici, btw).

0
ewh