Hi,

I am trying to pass a string to a MACRO using -D option in gcc. I am not getting desired output, below is snippet, please let me know what I am missing.

$ gcc -o finame -D CORE="op1_log.txt" finame.c

#define STR(x)  x

int main()
{
        FILE *fp;

        char filename[30];
        strcpy(filename,STR(CORE));

        fp = fopen(filename,"w");

        printf("%s\n",filename);
        if(fp == NULL)
                printf("Can not open File\n");
}

Dani AI

Generated

The shell is stripping your double quotes before they reach the preprocessor, so -DCORE="log.txt" becomes the three tokens log . txt. One reliable workaround is to pass the quotes through to the compiler by escaping them. Then you can use the macro directly as a string literal without any helper macros.

Example build command (POSIX shells like bash/zsh):

gcc -o finame -DCORE=\"log.txt\" finame.c

Minimal usage in C:

#include <stdio.h>

int main(void) {
    const char *filename = CORE;  /* CORE is a string literal here */
    FILE *fp = fopen(filename, "w");
    if (!fp) {
        perror("fopen");
        return 1;
    }
    printf("%s\n", filename);
    fclose(fp);
    return 0;
}

Notes and tips:

  • You can also keep the quotes intact with single quotes around the whole define: -D'CORE="log.txt"' (POSIX shells). On Windows cmd.exe, escape with backslashes similarly: cl /DCORE=\"log.txt\" ....
  • For paths with backslashes, escape them in the define: -DCORE=\"C:\\\\tmp\\\\out.txt\" (C needs \\ inside the string literal).
  • To verify what the preprocessor actually sees, dump macros with: echo | gcc -DCORE=\"log.txt\" -E -dM -. See GCC preprocessor options and macro stringification rules in GCC cpp manual.

Recommended Answers

All 10 Replies

Space between -D and CORE is the problem

$ gcc -o finame -DCORE="op1_log.txt" finame.c

HINT: You should ideally check if CORE is defined or not. So better code is:

#include <stdio.h>
#include <stdlib.h>

#define STR(x)  x

int main()
{
        FILE *fp;

        char filename[30];
#ifdef CORE
        strcpy(filename,STR(CORE));
#else
#error "Must provide -DCORE=value while compiling this file."
#endif

        fp = fopen(filename,"w");

        printf("%s\n",filename);
        if(fp == NULL)
                printf("Can not open File\n");
}

Source: gcc
You can also provide a default value using "#define"

Thanks for your reply but still same problem,, below error messgae

finame.c: In function ‘main’:
finame.c:12: error: ‘op1_log’ undeclared (first use in this function)
finame.c:12: error: (Each undeclared identifier is reported only once
finame.c:12: error: for each function it appears in.)

Thanks for your reply but still same problem,, below error messgae

finame.c: In function ‘main’:
finame.c:12: error: ‘op1_log’ undeclared (first use in this function)
finame.c:12: error: (Each undeclared identifier is reported only once
finame.c:12: error: for each function it appears in.)

Probably because of missing #includes..
Code I posted in my second post works for me.. haven't executed but it compiles with warnings.

Strange... not working for me..

Can you post the full command with output? Also re-post the code you're compiling, just to be sure..
I'm using gcc.

Here is the below code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define STR(x) x

int main()
{
        FILE *fp;
        char filename[30];
#ifdef CORE
        strcpy(filename,STR(CORE));
#else
#error "Must provide ...."
#endif
        fp = fopen(filename,"w");
        printf("%s\n",filename);
        if(fp == NULL)
                printf("Can not open File\n");
}

Compiler Error Message

[wipro@localhost code]$ gcc -o finame -DCORE="log.txt" finame.c 
finame.c: In function ‘main’:
finame.c:11: error: ‘log’ undeclared (first use in this function)
finame.c:11: error: (Each undeclared identifier is reported only once
finame.c:11: error: for each function it appears in.)

I am also using gcc

So close, yet so far. Isn't the preprocessor a bitch to work with for anything but the simplest of replacements? ;)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define XSTR(x) #x
#define STR(x) XSTR(x)

int main()
{
        FILE *fp;
        char filename[30];
#ifdef CORE
        strcpy(filename,STR(CORE));
#else
#error "Must provide ...."
#endif
        fp = fopen(filename,"w");
        printf("%s\n",filename);
        if(fp == NULL)
                printf("Can not open File\n");
}

Double quotes in the command line will be consumed by the shell, so you need to stringize the macro value to use it in string context. The STR macro gets that value and passes it on to another helper macro, XSTR, which uses the stringize preprocessor operator. Note that if you don't use this delegation and just use the stringize operator directly:

#define STR(x) #x

STR(CORE) will produce "CORE" rather than "log.txt".

A BIG THANK YOU Naure :)
It worked and also understood the root cause..great

Interesting that it compiled for me! Don't recall exactly what I passed on command line though..
Anyway, one other hint, gcc -E is quite helpful to find pre-proc related errors. Even if you have no errors I recommend you have a look at the pre-proce'd file at least once in your life.. :) $ gcc -E -o preprocd_finame.c -DCORE="log.txt" finame.c

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.