【问题标题】:passing identifier and type to macro将标识符和类型传递给宏
【发布时间】:2014-03-12 00:35:27
【问题描述】:

我正在尝试将标识符和类型传递给应该声明变量的宏

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

...

DECLARE_PARAM(char[100], title);

但我遇到了编译错误:

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

编辑

它适用于 char 或 int 等简单类型,有什么方法可以传递数组类型吗?

上下文

我实际上是在尝试创建一个可变参数函数,该函数接受一串由空格分隔的参数名称"title color other",然后是它们的值,因此它会像这样调用:

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

所以函数会给未指定的参数提供默认值

我写这个是为了测试,但现在我需要把这个样板代码放到这样的宏中 例如:

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

这是我写的测试

#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);

}

【问题讨论】:

  • 什么编译错误?
  • 有点猜谜游戏。请提供更多背景信息。
  • 不会是char titre[100],而不是char[100] 滴度吗?我不认为这与您的宏有关,它只是一个不正确的变量声明。
  • 好点,@computerfreaker ...char[100] 形式将是合法的 C++,但我不相信它会在 C 中工作。可以通过使用 typedef 来使其工作输入一个名字,我想......
  • 另外,请注意以双下划线 __ 开头的名称保留用于实现(用于任何目的)。你是在用它们玩火——如果你随后被烧伤,除了你自己以外,没有人会受到责备。同样,以下划线和大写字母开头的名称保留用于实现;事实上,您最好假设以下划线开头的标识符是保留的并且您不应该使用它们。

标签: c macros identifier


【解决方案1】:

正如其他人所指出的,char[100] foo 是合法的 Java,但不是合法的 C 或 C++,至少在我使用的方言中是这样。

我不保证,但你可以试试:

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

我怀疑这会奏效。 但是,使用宏向语言添加语法几乎总是一个坏主意。你真的没有为自己节省那么多工作,而且您正在创建一个不完全 C 的程序,这对于其他 C 程序员来说将更难使用。不要为了这种琐碎的事情而这样做,如果必须这样做,请将其记录下来

特别是因为你可以更清楚地说出同样的事情

typedef char Char100[100];
Char100 titre;

回应编辑“上下文”:

默认参数是一个非常不同的问题。为此,在调用通用版本之前定义包装函数,该函数采用参数的子集并填写缺失值。或者定义函数以识别保留值(null,或 -1,或其他不会发生的其他值)作为使用该参数的默认值的请求。比试图扭曲语言的语法要干净得多。

【讨论】:

  • 我知道我做的不好:D。如果可能的话,我只需要在 C 中使用默认参数。
  • 唯一的区别是额外的bool __exist_titre = false; 定义。但是您的回答基本上与我的评论相呼应;当我发布我的时,我假设你正在写你的。
  • @YoussefBouhjira:如果您想要 C++ 的功能,请使用 C++。这比与 C 战斗容易。
  • @JonathanLeffler 我希望我能 :( 。C 是一个要求
  • @JonathanLeffler 是的;同时思考。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多