En la línea de comandos de gcc, quiero definir una cadena como -Dname=Mary
, luego en el código fuente que quiero printf("%s", name);
imprimir Mary
.
¿Cómo podría hacerlo?
En la línea de comandos de gcc, quiero definir una cadena como -Dname=Mary
, luego en el código fuente que quiero printf("%s", name);
imprimir Mary
.
¿Cómo podría hacerlo?
Respuestas:
Dos opciones. Primero, evite las comillas para que la cáscara no se las coma:
gcc -Dname=\"Mary\"
O, si realmente quiere -Dname = Mary, puede encadenarlo, aunque es un poco 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));
}
Tenga en cuenta que STRINGIZE_VALUE_OF evaluará felizmente hasta la definición final de una macro.
La forma más portátil que encontré hasta ahora es usar \"Mary\"
: funcionará no solo con gcc sino con cualquier otro compilador de C. Por ejemplo, si intenta utilizarlo /Dname='"Mary"'
con el compilador de Microsoft, se detendrá con un error, pero /Dname=\"Mary\"
funcionará.
En Ubuntu estaba usando un alias que define CFLAGS, y CFLAGS incluía una macro que define una cadena, y luego uso CFLAGS en un Makefile. Tuve que escapar de los caracteres de comillas dobles y también de los caracteres \. Se veía algo como esto:
CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
1) DEFINES=-DLOGPATH=\"./logfile\" CFLAGS = -v $(DEFINES)....
2) DEFINES=-DLOGPATH=\\\"./logfile\\\" CFLAGS = "-v $(DEFINES)...."
usar la opción del compilador -v es útil para ver lo que está haciendo el preprocesador.
Aquí hay un ejemplo simple:
#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;
}
Si compilo:
$gcc test.c
Salida:
__DEBUG__ not defined
10
Si compilo:
$gcc -D __DEBUG__ test.c
Salida:
__DEBUG__ defined
30
Esta es mi solución para: -DUSB_PRODUCT=\""Arduino Leonardo\""
Lo usé en un archivo MAKE con:
GNU Make 3.81 (de GnuWin32)
y
avr-g ++ (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2
Los resultados en un archivo precompilado (opción -E para g ++) son:
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";
FYI: Aparentemente, incluso diferentes versiones de la misma cadena de herramientas en el mismo sistema pueden actuar de manera diferente en este sentido ... (Como en, parecería que esto sería un problema de paso de shell, pero aparentemente no se limita simplemente al shell).
Aquí tenemos xc32-gcc 4.8.3 vs. (avr-) gcc 4.7.2 (y varios otros) usando el mismo makefile y main.c, siendo la única diferencia 'make CC=xc32-gcc'
, etc.
CFLAGS += -D'THING="$(THINGDIR)/thing.h"'
ha estado en uso en muchas versiones de gcc (y bash) durante varios años.
Para hacer esto compatible con xc32-gcc (y a la luz de otro comentario que afirma que \ "es más portátil que '"), se tuvo que hacer lo siguiente:
CFLAGS += -DTHING=\"$(THINGDIR)/thing.h\"
ifeq "$(CC)" "xc32-gcc"
CFLAGS := $(subst \",\\\",$(CFLAGS))
endif
para hacer las cosas realmente confusas al descubrir esto: aparentemente una -D sin comillas con un // da como resultado un #define con un comentario al final ... ej.
THINGDIR=/thingDir/
-> #define /thingDir//thing.h
->#define /thingDir
(Gracias por la ayuda de la respuesta es aquí, por cierto).
Acabo de descubrir que una de nuestras aplicaciones no se compila en Ubuntu. Y dado que Linux y Windows no estaban de acuerdo en un enfoque común, usé esto:
NAME := "Mary"
ifeq ($(SystemRoot),)
# building on another OS
CFLAGS_ADD += -Dname=\"Mary\"
else
# building on Windows
CFLAGS_ADD += -Dname=\\\"Mary\\\"
endif
{
"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\""
}
]
}
Lo he hecho #define SHERAJ
aquí en VS Code. Funciona muy bien para la programación competitiva como:
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;
}
}
Me funcionó para VS Code tanto en Mac como en Windows. Otros métodos descritos aquí me gustaron "-Dname=\"SHERAJ\""
y "-Dname=\\\"SHERAJ\\\""
no funcionaron para mí.
Entonces la respuesta es "-DSHERAJ"
-DNAME=\"Mary\"
) para los tokens que va a definir de esta manera, para que se vean como otras macros.