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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2410976/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:24:29  来源:igfitidea点击:

How to define a string literal in gcc command line?

c++cgcccommand-linemacros

提问by richard

In gcc command line, I want to define a string such as -Dname=Mary, then in the source code I want printf("%s", name);to print Mary.
How could I do it?

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

回答by Arthur Shipkowski

Two options. First, escape the quotation marks so the shell doesn't eat them:

两种选择。首先,对引号进行转义,这样 shell 就不会吃掉它们:

gcc -Dname=\"Mary\"

Or, if you really want -Dname=Mary, you can stringize it, though it's a bit hacky.

或者,如果你真的想要 -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));
}

Note that STRINGIZE_VALUE_OF will happily evaluate down to the final definition of a macro.

请注意, STRINGIZE_VALUE_OF 会很高兴地评估到宏的最终定义。

回答by Johann

to avoid the shell "eating" the quotes and other characters, you might try single quotes, like this:

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

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

This way you have full control what is defined (quotes, spaces, special characters, and all).

这样您就可以完全控制定义的内容(引号、空格、特殊字符等)。

回答by psihodelia

Most portable way I found so far is to use \"Mary\"- it will work not only with gcc but with any other C compiler. For example, if you try to use /Dname='"Mary"'with Microsoft compiler, it will stop with an error, but /Dname=\"Mary\"will work.

到目前为止我发现的最便携的方法是使用\"Mary\"- 它不仅适用于 gcc,而且适用于任何其他 C 编译器。例如,如果您尝试/Dname='"Mary"'与 Microsoft 编译器一起使用,它会因错误而停止,但/Dname=\"Mary\"会起作用。

回答by Samuel

In Ubuntu I was using an alias that defines CFLAGS, and CFLAGS included a macro that defines a string, and then I use CFLAGS in a Makefile. I had to escape the double quote characters and as well the \ characters. It looked something like this:

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

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

回答by Hossein

Here is a simple example:

这是一个简单的例子:

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

If I compile:

如果我编译:

$gcc test.c

Output:

输出:

__DEBUG__ not defined
10

If I compile:

如果我编译:

$gcc -D __DEBUG__ test.c

Output:

输出:

__DEBUG__ defined
30

回答by bttcld

This is my solution for : -DUSB_PRODUCT=\""Arduino Leonardo\""
I used it in a makefile with:
GNU Make 3.81 (from GnuWin32)
and
avr-g++ (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2

这是我的解决方案:-DUSB_PRODUCT=\""Arduino Leonardo\""
我在一个 makefile 中使用它:
GNU Make 3.81(来自 GnuWin32)

avr-g++(AVR_8_bit_GNU_Toolchain_3.5.0_1662)4.9.2

The results in a precompiled file (-E option for g++) is:
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";

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

回答by George Valkov

I just found that one of our applications does not compile on Ubuntu. And since Linux and Windows didn't agree on a common approach, I used this:

我刚刚发现我们的一个应用程序无法在 Ubuntu 上编译。由于 Linux 和 Windows 在通用方法上没有达成一致,我使用了这个:

NAME := "Mary"

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

回答by ewh

FYI: Apparently even different versions of the same toolchain on the same system can act differently in this regard... (As in, it would seemthis would be a shell-passing issue, but apparently it's not limited to merely the shell).

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

Here we have xc32-gcc 4.8.3 vs. (avr-)gcc 4.7.2 (and severalothers) using the same makefile and main.c, the only difference being 'make CC=xc32-gcc', etc.

这里我们有 xc32-gcc 4.8.3 与 (avr-)gcc 4.7.2(以及其他几个)使用相同的 makefile 和 main.c,唯一的区别是'make CC=xc32-gcc'等。

CFLAGS += -D'THING="$(THINGDIR)/thing.h"'has been in-use on manyversions of gcc (and bash) over several years.

CFLAGS += -D'THING="$(THINGDIR)/thing.h"'多年来一直在许多版本的 gcc(和 bash)上使用。

In order to make this compatible with xc32-gcc (and in light of another comment claiming that \" is more portable than '"), the following had to be done:

为了使其与 xc32-gcc 兼容(并且根据另一条评论声称 \" 比 '" 更便携),必须执行以下操作:

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

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

to make things reallyconfusing in discovering this: apparently an unquoted -D with a // results in a #define with a commentat the end... e.g.

在发现这一点时让事情变得非常令人困惑:显然带有 // 的未加引号的 -D 导致 #define在末尾带有注释......例如

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

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

(Thanks for the help from answershere, btw).

(感谢这里的答案帮助,顺便说一句)。