Как определить строковый литерал в командной строке gcc? - PullRequest
65 голосов
/ 09 марта 2010

В командной строке gcc я хочу определить строку, такую ​​как -Dname=Mary, затем в исходном коде я хочу printf("%s", name); напечатать Mary.
Как я мог это сделать?

Ответы [ 7 ]

80 голосов
/ 09 марта 2010

Два варианта.Во-первых, избегайте кавычек, чтобы оболочка их не сожрала:

gcc -Dname=\"Mary\"

Или, если вы действительно хотите -Dname = Mary, вы можете ее преобразовать в строку, хотя она немного хакерская.

#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));
}

Обратите внимание, что STRINGIZE_VALUE_OF успешно выполнит оценку вплоть до окончательного определения макроса.

24 голосов
/ 31 октября 2011

, чтобы оболочка не «съела» кавычки и другие символы, вы можете попробовать одинарные кавычки, например:

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

Таким образом, вы получаете полный контроль над тем, что определено (кавычки, пробелы, специальные символы и все).

6 голосов
/ 05 марта 2013

Самый портативный способ, который я нашел до сих пор, это использовать \"Mary\" - он будет работать не только с gcc, но и с любым другим компилятором C Например, если вы попытаетесь использовать /Dname='"Mary"' с компилятором Microsoft, он остановится с ошибкой, но /Dname=\"Mary\" будет работать.

5 голосов
/ 05 марта 2013

В Ubuntu я использовал псевдоним, который определяет CFLAGS, и CFLAGS включал макрос, который определяет строку, а затем я использую CFLAGS в Makefile. Я должен был избежать двойных кавычек, а также символов \. Выглядело это примерно так:

CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
1 голос
/ 21 июля 2018

Вот простой пример:

#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;
}

Если я скомпилирую:

$gcc test.c

Выход:

__DEBUG__ not defined
10

Если я скомпилирую:

$gcc -D __DEBUG__ test.c

Выход:

__DEBUG__ defined
30
0 голосов
/ 02 февраля 2017

Это мое решение для: <strong>-DUSB_PRODUCT=\""Arduino Leonardo\""</strong>
Я использовал его в make-файле с:
GNU Make 3.81 (из GnuWin32)
и
avr-g ++ (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2

Результаты в предварительно скомпилированном файле (опция -E для g ++):
const u8 STRING_PRODUCT[] &#95;&#95;attribute__((&#95;&#95;progmem__)) = "Arduino Leonardo";

0 голосов
/ 04 июля 2015

К вашему сведению: очевидно, что разные версии одной и той же цепочки инструментов в одной и той же системе могут действовать по-разному в этом отношении ... (Например, может показаться , это будет проблема передачи оболочки, но, очевидно, она не ограничивается только оболочкой).

Здесь мы имеем xc32-gcc 4.8.3 против (avr-) gcc 4.7.2 (и несколько другие) используя один и тот же makefile и main.c, с той лишь разницей, что 'make CC=xc32-gcc' и т. д.

CFLAGS += -D'THING="$(THINGDIR)/thing.h"' использовался на многих версиях gcc (и bash) в течение нескольких лет.

Чтобы сделать это совместимым с xc32-gcc (и в свете другого комментария, утверждающего, что \ "более переносим, ​​чем '"), необходимо сделать следующее:

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

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

чтобы сделать вещи действительно запутанными при обнаружении этого: очевидно, что не-кавычка -D с // приводит к #define с комментарием в конце ... например

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

(Спасибо за помощь от ответа s здесь, кстати).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...