On the 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?
On the 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?
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.
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).
The most portable way I found so far was 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 a Microsoft compiler, it will stop with an error, but /Dname=\"Mary\"
will work.
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\\\" "'
1) DEFINES=-DLOGPATH=\"./logfile\" CFLAGS = -v $(DEFINES)....
2) DEFINES=-DLOGPATH=\\\"./logfile\\\" CFLAGS = "-v $(DEFINES)...."
Using the -v compiler option is useful to see what the preprocessor is doing.
Dec 15, 2017 at 12:13
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";
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
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).
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
Consider:
{
"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 SHERAJ
here in Visual Studio 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 Visual Studio 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"
.
-DNAME=\"Mary\"
)for tokens that you're going to define this way, so that they look like other macros.