如何在gcc命令行中定义字符串文字?

时间:2010-03-09 17:13:31

标签: c++ c gcc command-line macros

在gcc命令行中,我想定义一个字符串,例如-Dname=Mary,然后在源代码中我希望printf("%s", name);打印Mary
我怎么能这样做?

9 个答案:

答案 0 :(得分:80)

两个选项。首先,逃避引号,以便shell不吃它们:

gcc -Dname=\"Mary\"

或者,如果你真的想要-Dname = Mary,你可以将其字符串化,虽然它有点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));
}

请注意,STRINGIZE_VALUE_OF将很乐意评估宏的最终定义。

答案 1 :(得分:24)

为避免shell“吃掉”引号和其他字符,您可以尝试单引号,如下所示:

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

通过这种方式,您可以完全控制所定义的内容(引号,空格,特殊字符和所有内容)。

答案 2 :(得分:6)

到目前为止,我发现的大多数可移植方式都是使用\"Mary\" - 它不仅适用于gcc,还适用于任何其他C编译器。例如,如果您尝试将/Dname='"Mary"'与Microsoft编译器一起使用,则会因错误而停止,但/Dname=\"Mary\"将起作用。

答案 3 :(得分:5)

在Ubuntu中我使用的是定义CFLAGS的别名,CFLAGS包含一个定义字符串的宏,然后我在Makefile中使用CFLAGS。我不得不逃避双引号字符和\字符。它看起来像这样:

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

答案 4 :(得分:1)

这是一个简单的例子:

#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

答案 5 :(得分:0)

仅供参考:显然,即使是同一系统上相同工具链的不同版本,在这方面也会有不同的行为...... (因为,它似乎似乎这将是一个shell传递问题,但显然它不仅仅局限于shell)。

这里我们有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/ - &gt; #define /thingDir//thing.h - &gt; #define /thingDir

(感谢您在这里回答 s 的帮助,顺便说一下。)

答案 6 :(得分:0)

我刚刚发现我们的一个应用程序无法在Ubuntu上编译。而且由于Linux和Windows在通用方法上未达成共识,因此我使用了以下方法:

NAME := "Mary"

ifeq ($(SystemRoot),)
    # building on another OS
    CFLAGS_ADD += -Dname=\"Mary\"
else
    # building on Windows
    CFLAGS_ADD += -Dname=\\\"Mary\\\"
endif

答案 7 :(得分:0)

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++.exe build active file",
            "command": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe",
            "args": [
                "-g",
                "-DSHERAJ",
                "${file}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "compiler: \"C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe\""
        }
    ]
}

我已经在 VS Code 中完成了#define SHERAJ。它非常适合竞争性编程,因为 -

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    #ifdef SHERAJ
        freopen("input.txt"  , "r", stdin);
    #endif
    int T;
    cin>>T;
    for(int test_case = 1;test_case<=T;test_case++) {
        cout<<"Hello World"<<endl;
    }
}

它适用于 Mac 和 Windows 上的 VS Code。此处描述的其他方法(如 "-Dname=\"SHERAJ\"""-Dname=\\\"SHERAJ\\\"")对我不起作用。

所以答案是"-DSHERAJ"

答案 8 :(得分:-1)

这是我的解决方案:-DUSB_PRODUCT=\""Arduino Leonardo\""
我在makefile中使用它:
GNU Make 3.81(来自GnuWin32)
 和
avr -g ++(AVR_8_bit_GNU_Toolchain_3.5.0_1662)4.9.2

预编译文件中的结果(g ++的-E选项)是:
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";