-2

I'm trying to assign data type to world but unable to figure it out.

#include <stdarg.h>
#include <stdio.h>
#define TRACE(arg)  TraceDebug arg ;\
                       void TraceDebug(const char* format, ...);            

void TraceDebug(const char*  format, ...)
{
        char buffer[256];
        va_list args;
        va_start(args, format);
        vprintf(format, args);        
        va_end(args);
}

int main(void)
{
    int a =55;
    TRACE((Hello,a));
    return 0;
}

Below is the error statement in detail.

main.c: In function 'main':
main.c:28:12: error: 'Hello' undeclared (first use in this function)
     TRACE((Hello,a));
            ^
main.c:13:32: note: in definition of macro 'TRACE'
 #define TRACE(arg)  TraceDebug arg ;\
                                ^
main.c:28:12: note: each undeclared identifier is reported only once for each function it appears in
     TRACE((Hello,a));
            ^
main.c:13:32: note: in definition of macro 'TRACE'
 #define TRACE(arg)  TraceDebug arg ;\
                                ^

Is there anyway possible to declare Hello as a variable, after declaring I need to get the address of the variable.

In simple I want to change the below code into a variadic function arguments for example #define QU(arg1,arg2) as #define QU(arg1,...) since variadic macro is not supported am using variadic functions.

#define TRACE(arg1)  QU arg1
#define QU(arg1,arg2)         {static const char arg1; \
                              printf("%p\n",(void*)&arg1);\
                              printf("%d\n",arg2);}\

int main(void)
{
    int aaa =333;
    int bbb =444;
    TRACE((Hello,aaa));
    TRACE((Hello2,bbb));
    return 0;
}
w.jayson
  • 27
  • 5
  • *Is there anyway possible to declare Hello as a variable* Umm, maybe declare it as a variable? – Andrew Henle Jun 22 '18 at 11:49
  • The simple answer would be to call the macro as `TRACE(("Hello", a));`, however that contradicts your [previous question](https://stackoverflow.com/questions/50962336/how-to-convert-a-string-to-variable-name-using-macro). What is it you **really** want to do? – dbush Jun 22 '18 at 11:49
  • If I do that I will not be able to de-stringify hello to make as a variable. – w.jayson Jun 22 '18 at 11:51
  • @AndrewHenle need to use through macro not in a direct way. :) – w.jayson Jun 22 '18 at 11:53
  • 1
    Your updated example just seems to print the address of an arbitrary variable that it never uses again. I also don't see an example of where you'd want to stringify. How abut you show an example of what you want that involves using "Hello" as both a string *and* a variable name, and why you think you need that? – dbush Jun 22 '18 at 11:55
  • Again, what are you **actually** trying to accomplish by doing all this? There's probably a better approach to the "real" problem. – dbush Jun 22 '18 at 11:56
  • if i change the string to variable i can reduce the memory size, The address of variable will be mapped with a file so that i can decode `hello` later. – w.jayson Jun 22 '18 at 12:01
  • So you want to keep the strings of your log messages in a separate file, and read them from the file when needed? – dbush Jun 22 '18 at 12:22
  • From your last edit, I think it is becoming more clear what you want to do. You want to have a variable argument list to pass variables existing in your program that you want to place on a Trace list for debugging purposes. (is that close?) If that is the case, in a variadic function prototype, the ellipses ( `...` ) follows the `type` of variable that can be repeated. Are you always going to pass the same `type` to this function? – ryyker Jun 22 '18 at 12:22
  • _if i change the string to variable i can reduce the memory size_, This suggests you want to store the address of the variable, instead of the content of the variable for the purpose of saving memory in your file. If that is the case, the address of a variable is synonymous with its _symbol_ or _name_. – ryyker Jun 22 '18 at 12:32
  • @ryyker _(is that close?)_ yes, that's the thing am trying to do... _Are you always going to pass the same type to this function?_ Ahh, `type` will be like `TRACE(("Hello", a,"world"));` – w.jayson Jun 22 '18 at 12:45
  • @ryyker _the address of a variable is synonymous with its symbol or name_ I dint get that. – w.jayson Jun 22 '18 at 12:46
  • @dbush _So you want to keep the strings of your log messages in a separate file, and read them from the file when needed?_ Ya you got the point. – w.jayson Jun 22 '18 at 12:48
  • See re-worked answer. I think it does (mechanically) what you have described here. It stores the address of variadic argument string content into variables, then puts a string form of the address of each of those variables into a storage file. – ryyker Jun 22 '18 at 14:57

1 Answers1

0

1) (title) How to declare the data type for variable arguments?
2) (1st question) I'm trying to assign data type to world but unable to figure it out.

1) The data type for the variadic argument (represented by the ellipses: ... ) is always the type of the variable preceding the ellipses . For this prototype:

int variadicFunc(int a, const char *b, ...);
                        ^^^^^^^^^^     ^^^
                        type           assumes the type const char *

2) From content of your question only, the answer could be to be use a typedef statement:

typedef char World;  // a new type 'World' is created   

But there are clarifications in the comments:

  • if i change the string to variable i can reduce the memory size,... (you)
  • You want to have a variable argument list to pass variables existing in your program that you want to place on a Trace list for debugging purposes. (is that close?)... (me)
  • (is that close?) yes, that's the thing am trying to do... Are you always going to pass the same type to this function? Ahh, type will be like TRACE(("Hello", a,"world")); (you)

It appears you want to enter a variable number of either string literals, or string variables as function arguments, then for those items to be placed into variables, then the addresses of those variables to be stored in a file, for the purpose of saving space.

The following code illustrates how you can pass a variable number of strings (in different forms) into a function, and have the address and content retained into a struct. From this, you should be able to adapt from what I have done here, to something more useful to your needs. Note, I have reserved the first string argument to be used a file location to store addresses.

#define MAX_LEN 200

typedef struct {
    unsigned int addr;
    char str[MAX_LEN];
} DATA;


int variadicFunc(int argCount, const char *str, ...);

int main(void)
{
    char a[] = {"this is a string"};
    char b[] = {"another string"};
    char c[] = {"yet another string"};

    //           count   non-variable v1 v2      v3       v4
    variadicFunc(4, ".\\storage.txt", a, b, "var string", c);
    //           ^count of variable argument list  


    return 0;
}
int variadicFunc(int argCount, const char *str, ...)
{
    va_list arg;
    int i;
    char sAddr[10];

    DATA *d = calloc(argCount, sizeof(*d));

    va_start(arg, str);
    FILE *fp = fopen(str, "w");//using first string as filename to populate
    if(fp)
    {
        for(i=0;i<argCount;i++)
        {
            // retain addresses and content for each string
            strcpy(d[i].str, va_arg(arg, const char *));
            d[i].addr = (unsigned int)&d[i].str[i];
            sprintf(sAddr, "%X\n", d[i].addr);
            fputs(sAddr, fp);
        }
        fclose(fp);
    }

    return 0;   
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • If I do that I will not be able to de-stringify hello to make as a variable. – w.jayson Jun 22 '18 at 11:51
  • @w.jayson - I am not sure what you are asking, or what your real need is. If you want to make the term `Hello` a C type, then use `typedef` to make it a type. If you want to use it as a variable, simply use the `char` type to create it as a variable, as shown above. – ryyker Jun 22 '18 at 11:59
  • There are so many different variables( `hello`, `asd_grd` etc..) which needs to be converted, so its not possible to typedef it. So am preferring for macro. – w.jayson Jun 22 '18 at 12:04
  • @w.jayson - If you are able to give a usage example, it may shed light on what problem it is you are trying to solve. Every variable has a type, an address, its content (or what is stored at the address). Are these the kind of things you are interested in using somehow? – ryyker Jun 22 '18 at 12:14
  • The below code is working fine in online compiler but in my compiler it gives an error like `anonymous variadic macros were introduced in C99` so am trying to implement variadic function instead of variadic macro. `#define TRACE(arg1,...) static const char arg1 =0; \` ` printf("%d\n",__VA_ARGS__); \` printf("addr = %p \n",&arg1);` `int main(void)` `{` ` int a=222;` ` TRACE(Hello,a);` ` return 0;` `}` – w.jayson Jun 22 '18 at 12:18
  • That is not working. Try adding a 3rd value to it and you'll see it fail as there is nothing in the call to `printf` to tell it to expect another variable. – Chris Turner Jun 22 '18 at 12:23
  • @ChrisTurner it is working when i add the third argument ` TRACE(Hello,a,"world");` i have not printed in the macro. any better solution! – w.jayson Jun 22 '18 at 12:42