Gccコマンドラインでは、_-Dname=Mary
_などの文字列を定義し、ソースコードではprintf("%s", name);
でMary
を出力します。
どうすればできますか?
2つのオプション。最初に、シェルがそれらを食べないように引用符をエスケープします。
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は、マクロの最終的な定義まで喜んで評価することに注意してください。
シェルが引用符やその他の文字を「食べる」ことを避けるために、次のように一重引用符を試してください。
gcc -o test test.cpp -DNAME='"Mary"'
このようにして、定義するもの(引用符、スペース、特殊文字、およびすべて)を完全に制御できます。
私がこれまでに見つけた最も移植性の高い方法は、\"Mary\"
を使用することです。gccだけでなく、他のCコンパイラでも動作します。たとえば、Microsoftコンパイラで/Dname='"Mary"'
を使用しようとすると、エラーで停止しますが、/Dname=\"Mary\"
は機能します。
Ubuntuでは、CFLAGSを定義するエイリアスを使用していました。CFLAGSには文字列を定義するマクロが含まれていたため、MakefileでCFLAGSを使用します。二重引用符文字と\文字もエスケープする必要がありました。次のように見えました。
CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
以下に簡単な例を示します。
#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
参考までに、どうやら同じシステム上の同じツールチェーンの異なるバージョンでさえ、この点で異なる動作をする可能性があります...(たとえば、seemシェルを渡す問題であるが、明らかにシェルだけに限定されない)。
ここでは、同じmakefileとmain.cを使用するxc32-gcc 4.8.3と(avr-)gcc 4.7.2(およびseveralその他)があります。 、唯一の違いは_'make CC=xc32-gcc'
_などです。
CFLAGS += -D'THING="$(THINGDIR)/thing.h"'
は数年にわたってgcc(およびbash)のmanyバージョンで使用されています。
これを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ここで、btw)。