Добавление параметров по умолчанию к variadic макросу

Действительно ли возможно добавить параметры по умолчанию перед аргументом переменной в variadic макросе? например, у меня есть версия макроса что-то как

#define MACRO(arg1, ...) func(arg1, ##__VA_ARGS__)

Я хотел бы добавить еще 2 параметра по умолчанию в макросе перед аргументами переменной так, чтобы он не влиял на предыдущую версию. Как:

#define MACRO(arg1, arg2 = "", arg3 = "", ...) func(arg1, arg2, arg3, ##__VA_ARGS__)

Любая справка ценилась бы.

5
задан Brian Tompsett - 汤莱恩 11 June 2016 в 21:29
поделиться

2 ответа

Просто используйте next в этом контексте:

$ irb
irb(main):001:0> def thing(*args, &block)
irb(main):002:1>   value = block.call
irb(main):003:1>   puts "value=#{value}"
irb(main):004:1> end
=> nil
irb(main):005:0>
irb(main):006:0* thing {
irb(main):007:1*   return 6 * 7
irb(main):008:1> }
LocalJumpError: unexpected return
        from (irb):7:in `block in irb_binding'
        from (irb):2:in `call'
        from (irb):2:in `thing'
        from (irb):6
        from /home/mirko/.rvm/rubies/ruby-1.9.1-p378/bin/irb:15:in `<main>'
irb(main):009:0> thing { break 6 * 7 }
=> 42
irb(main):011:0> thing { next 6 * 7 }
value=42
=> nil
  • return всегда возвращает из метода, но при тестировании этого фрагмента в irb у вас нет метода, поэтому LocalJumpError
  • break возвращает значение из блока и завершает его вызов. Если блок был вызван с помощью hield или .call , то break breaks from this iterator
  • next возвращает значение из блока и завершает его вызов. Если блок был вызван по доходности или .call , то next возвращает значение в строку, где доходность называлась
-121--814742-

используйте shell _ exec для выполнения команды на os-level? для linux/unix box это может работать;

$output=shell_exec('ls -t1');
-121--2970289-

Я не думаю, что это возможно. Каким образом компилятор/препроцессор может узнать, являются ли второй и третий аргументы частью переменных аргументов, или переопределить значения по умолчанию? Именно поэтому параметры со значениями по умолчанию должны находиться в последней позиции функции.

Я боюсь, что вам придется иметь два макроса или три, если вы можете указать arg2 и использовать значение по умолчанию arg3, но это подвержено ошибкам.

#define MACRO(arg1, ...) func(arg1, "", "", ##__VA_ARGS__)
#define MACRO2(arg1, arg2, ...) func(arg1, arg2, "", ##__VA_ARGS__)
#define MACRO3(arg1, arg2, arg3, ...) func(arg1, arg2, arg3, ##__VA_ARGS__)
4
ответ дан 14 December 2019 в 01:06
поделиться

Что вы можете сделать:

struct foo {
    int   aaa;
    char  bbb;
    char  *ccc;
};

#define BAR(...)   bar((struct foo){__VA_ARGS__})

void bar(struct foo baz)
    /* set defaults */
    if (!baz.aaa)
        baz.aaa = 10;
    if (!baz.bbb)
        baz.bbb = 'z';
    if (!baz.ccc)
        baz.ccc = "default";

    printf("%d, %c, %s\n", baz.aaa, baz.bbb, baz.ccc);
}

...
BAR();                     // prints "10, z, default"
BAR(5);                    // prints "5, z, default"
BAR(5,'b');                // prints "5, b, default"
BAR(5, 'b', "something");  // prints "5, b, something"

Плохая вещь - нулевой параметр обрабатывается как никакой параметр, например BAR (0, 'c') создаст строку 10, c, по умолчанию

5
ответ дан 14 December 2019 в 01:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: