1
votes

I'm trying to pass an identifier and a type to a macro that should declare the variable

#define DECLARE_PARAM(TYPE, PARAM) \
  TYPE PARAM; \
  gboolean __exist_##PARAM = FALSE

...

DECLARE_PARAM(char[100], title);

but I'm getting compilation errors :

expected identifier or '(' before '[' token
   DECLARE_PARAM(char[100], title);
                     ^

EDIT

It works with simple types such char or int, is there a way I can pass an array type?

CONTEXT

I'm actually trying to make a variadic function that takes a string of parameters name separated by spaces "title color other" and then their values so it would be called like this :

create_window("color title", "blue", "My window");

so the function would give default values to the none specified argument.

I wrote this as a test, but now I need to put this boilerplate code into a macro like this for example :

DEFAULT_PARAM(title, char[100], "My window");

here is the test I wrote

#define DECLARE_PARAM(TYPE, PARAM) \
  TYPE PARAM; \
  gboolean __exist_##PARAM = FALSE

GtkWidget *fenetre_creer(char *keys, ...)
{
  va_list args;

  DECLARE_PARAM(char[100], titre);
  DECLARE_PARAM(char[100], icon);
  DECLARE_PARAM(int, padding);

  GList *argList = read_args(keys);
  int nombreArguments = g_list_length(argList);

  va_start(args, nombreArguments);

  GList *iterator = argList;
  while(iterator)
    {
      char *argument = iterator->data;
      if(strcmp(argument, "titre"))
        {
          strcpy(titre, va_arg(args, char*));
          _titre_param = TRUE;
        }
      else if(strcmp(argument, "icon"))
        {
          strcpy(icon, va_arg(args, char*));
          _icon_param = TRUE;
        }
      else if (strcmp(argument, "padding"))
        {
          padding = va_arg(args, int);
          _padding_param = TRUE;
        }
      iterator = iterator->next;
    }
  var_end();

  if(!__exist_titre)
    strcpy(titre, "Titre de la fenetre");
  if(!__exist_padding)
    padding = 10;
  if(!__exist_icon)
    strcpy(icon, "");

  printf("titre : %s\n", titre);
  printf("padding : %d\n", padding);
  printf("icon : %s\n", icon);

}
1
What compilation errors? - Benesh
It's a bit of a guessing game. Please provide more context. - david.pfx
Wouldn't it be char titre[100], not char[100] titre? I don't think this is about your macro, it's just an incorrect variable declaration. - cf stands with Monica
good point, @computerfreaker ... the char[100] form would be legal C++, but I'm not convinced it would work in C. It could be made to work by using typedef to give that type a name, I suppose... - keshlam
Also, note that names starting with double underscore __ are reserved for the implementation (for any purpose). You are playing with fire using them — and will have no-one but yourself to blame if you subsequently get burned. Similarly, names starting with underscore and a capital letter are reserved for the implementation; in fact, you'd do well to assume that identifiers starting with an underscore are reserved and that you should not use them. - Jonathan Leffler

1 Answers

2
votes

As others have noted, char[100] foo is legal Java but not legal C or C++, at least in the dialects I've used.

I'm not guaranteeing it, but you could try:

typedef char Char100[100];
DECLARE_PARAM(Char100, titre);

I suspect that would work. HOWEVER, using macros to add syntax to the language is almost always a bad idea. You really aren't saving yourself that much work, and you're creating a not-quite-C program which will be harder for other C programmers to work with. Don't do it for trivial things like this, and if you must do it document it to death.

Especially since you can say the same thing more clearly as

typedef char Char100[100];
Char100 titre;

RESPONDING TO EDIT FOR "CONTEXT":

Default parameters is a very different question. For that, define wrapper functions which take a subset of the arguments and fill in the missing values before calling the general version. Or define the function to recognize a reserved value (null, or -1, or something else that won't otherwise occur) as a request to use the default value for that parameter. Much cleaner than trying to warp the syntax of the language.