How to define a string literal in gcc command line?

C++CGccCommand LineMacros

C++ Problem Overview


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?

C++ Solutions


Solution 1 - C++

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

gcc -Dname=\"Mary\"

Or, if you really want -Dname=Mary, you can stringize it, though it's a bit 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.

Solution 2 - C++

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).

Solution 3 - C++

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.

Solution 4 - C++

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:

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

Solution 5 - C++

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

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

Solution 6 - C++

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

Solution 7 - C++

FYI: Apparently even different versions of the same toolchain on the same system can act differently in this regard... (As in, it would seem this 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 several others) using the same makefile and main.c, the only difference being 'make CC=xc32-gcc', etc.

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

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:

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

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

to make things really confusing in discovering this: apparently an unquoted -D with a // results in a #define with a comment at the end... e.g.

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

(Thanks for the help from answers here, btw).

Solution 8 - C++

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:

NAME := "Mary"

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

Solution 9 - C++

{
	"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\""
		}
	]
}

I have done #define SHERAJhere in VS Code. It works great for competitive programming as -

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

It worked for me for VS Code on both Mac and Windows. Other methods described here like "-Dname=\"SHERAJ\"" and "-Dname=\\\"SHERAJ\\\"" did not work for me.

So the answer is "-DSHERAJ"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrichardView Question on Stackoverflow
Solution 1 - C++Arthur ShipkowskiView Answer on Stackoverflow
Solution 2 - C++JohannView Answer on Stackoverflow
Solution 3 - C++psihodeliaView Answer on Stackoverflow
Solution 4 - C++SamuelView Answer on Stackoverflow
Solution 5 - C++bttcldView Answer on Stackoverflow
Solution 6 - C++HosseinView Answer on Stackoverflow
Solution 7 - C++ewhView Answer on Stackoverflow
Solution 8 - C++George ValkovView Answer on Stackoverflow
Solution 9 - C++zeitgeistView Answer on Stackoverflow