标签: variadic-macros

“gnu-zero-variadic-macro-arguments”可以安全地忽略吗?

考虑以下代码(实例)

#define TEST_VA(mX, ...) TEST
#define STRINGIFY_IMPL(mX) #mX
#define STRINGIFY(mX) STRINGIFY_IMPL(mX)

#include <iostream>

int main()
{
    std::cout << STRINGIFY(TEST_VA(1)) << std::endl;
    std::cout << STRINGIFY(TEST_VA()) << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

clang++ 3.4抱怨:

main.cpp:9:37: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments]
    std::cout << STRINGIFY(TEST_VA(1)) << std::endl;
                                    ^
main.cpp:1:9: note: macro 'TEST_VA' defined here
#define TEST_VA(mX, ...) TEST
        ^
main.cpp:10:33: warning: must specify at least one argument for '...' parameter of variadic macro …
Run Code Online (Sandbox Code Playgroud)

c++ warnings c-preprocessor variadic-macros c++11

6
推荐指数
1
解决办法
5885
查看次数

可变参数和 x64

va_arg\ va_start\ va_list\va_end宏在 x64 中如何工作?

i386 中的调用约定在堆栈上传递参数,因此宏只是增加一些指向堆栈基址的指针并转发它。然而,在 x64 中,所有参数都是通过寄存器传递的......那么那里会发生什么呢?被调用函数如何知道哪些寄存器用于传递参数以确保它不会破坏它们?

c x86-64 calling-convention variadic-macros

6
推荐指数
1
解决办法
3104
查看次数

如何单独输出发送到仅采用可变参数的宏的第一个参数

我尝试获取发送到可变参数宏的第一个实际参数.这是我试过的,哪些在VS2010中不起作用:

#define FIRST_ARG(N, ...) N
#define MY_MACRO(...) decltype(FIRST_ARG(__VA_ARGS__))
Run Code Online (Sandbox Code Playgroud)

当我查看预处理器输出时,我看到FIRST_ARG返回发送给MY_MACRO... 的整个参数列表

另一方面,当我尝试:

FIRST_ARG(1,2,3)
Run Code Online (Sandbox Code Playgroud)

它按预期扩展到1.

这似乎是臭名昭着的两级concat宏解决问题的逆转.我知道"宏参数在插入宏体之前已完全展开"但这似乎对我没有帮助,因为我不明白这意味着什么......和__VA_ARGS__

显然是__VA_ARGS__绑定,N只是稍后评估.我尝试了几种额外的宏观方法,但没有用.

c++ macros c-preprocessor variadic-macros c++11

5
推荐指数
1
解决办法
4053
查看次数

使用可变参数宏或模板来实现一组函数

我有一组用于实例化和初始化一组对象的方法.它们看起来几乎相同,除了传递给Init函数的参数数量:

ObjectType* CreateObjectType(Arg1 a1, Arg2 arg2, ... ArgN aN)
{
    ObjectType* object = new ObjectType();
    [...]
    object->Init(this, a1, a2, ..., aN);
    [...]
    return object;
}
Run Code Online (Sandbox Code Playgroud)

请注意,除了要传递给Init函数之外,不能在任何地方使用参数.

我想找到一种方法来实现所有这些,而无需为每个对象类型复制代码.


我尝试使用可变参数宏,结果如下(无效):

#define CREATE_OBJECT_IMPL(ObjectType, ...)    \
ObjectType* Create##ObjectType##(__VA_ARGS__)  \
{                                              \
    ObjectType* object = new ObjectType();     \
    [...]
    object->Init(this, ##__VA_ARGS__);         \
    [...]
    return object;                             \
}

// This is the result I am trying to achieve :
CREATE_OBJECT_IMPL(MyFirstObject, bool, float)
CREATE_OBJECT_IMPL(MySecondObject, int)
CREATE_OBJECT_IMPL(MyThirdObject)
Run Code Online (Sandbox Code Playgroud)

现在,在这个实现中,我使用VA_ARGS两次,两次都不正确:

  • 在第一种情况下,我想要一个包含我指定类型的参数列表(Arg1 a1,Arg2 a2 ......)

  • 在第二种情况下,我想通过它们的名称(Init(a1,a2 ...))来调用这些参数. …

c++ variadic-templates variadic-macros

5
推荐指数
1
解决办法
3018
查看次数

检测C宏中是否存在参数

如何定义一个C宏IFARGS(YES, NO, ...),以便IFARGS在没有其他参数的情况下进行NO调用,并IFARGS使用一个或多个参数进行调用YES

我有一个使用GCC的答案(见下文),但如果可能的话,我更喜欢C99(或其不可能的证明).

c c-preprocessor variadic-macros

5
推荐指数
2
解决办法
1333
查看次数

字符串化 __VA_ARGS__(C++ 可变参数宏)

让我们

class Item{
public:
    Item(int id,const char *name,const char *props=NULL);
};
Run Code Online (Sandbox Code Playgroud)

我想写:

ITEM(1,FIRST);
ITEM(2,SECOND, WithSomeProps);
Run Code Online (Sandbox Code Playgroud)

用宏

#define ITEM(ID,NAME,...) new Item(ID,NAME, #__VA_ARGS__ )
Run Code Online (Sandbox Code Playgroud)

#__VA_ARGS__在 gcc 上编译得很好,但在 VStudio 上会出错。是否有可靠且便携的解决方案?

我想ITEM()在 .h 文件中有一个集合,该文件将被多次包含在不同的 #definitions of .h 文件中ITEM

c++ stringification c-preprocessor variadic-macros

5
推荐指数
1
解决办法
1524
查看次数

每个参数的可变宏替换是否可能?

我现在读了很多关于可变参数宏的问题,但似乎并没有人回答最简单的问题:

#define IDENTITY(x) x
#define IDENTITY_FOR_ALL(...) ???
Run Code Online (Sandbox Code Playgroud)

有没有办法IDENTITY_FOR_ALL扩展IDENTITY(X)所有参数?任意数量的参数也可能吗?

c++ c-preprocessor variadic-macros c++11

5
推荐指数
1
解决办法
840
查看次数

C 预处理器:迭代地将宏扩展为逗号分隔的列表

在后C 预处理器递归宏中使用 Paul Fultz II 的解决方案,我想扩展无限数量的括号宏参数,例如

#define MY_CHAIN (alpha) (beta) (gamma)
Run Code Online (Sandbox Code Playgroud)

到一个逗号分隔的列表中,该列表可以传递给可变参数宏,例如

CHAIN_COMMA(MY_CHAIN) // alpha, beta, gamma
Run Code Online (Sandbox Code Playgroud)

在下面的示例中[alpha] [beta] [gamma],我可以扩展为大括号并使用我尝试过的所有内容分隔列表,但逗号除外alpha :: beta :: gamma

这是我的完整(编译)代码:

#include <iostream>
using namespace std;

// unrelated macro utilities
#define SEE(expression) cout << #expression ": " << STR(expression) << endl;
#define CMD(function, ...) function(__VA_ARGS__)
#define STR(s) CMD(STR_, s)
#define STR_(s) #s

// concatenation
#define CAT(x, y) CAT_(x, y)
#define CAT_(x,y) x ## y // error from CHAIN_COMMA: passed 4 …
Run Code Online (Sandbox Code Playgroud)

comma-operator c-preprocessor variadic-macros

5
推荐指数
1
解决办法
1200
查看次数

用于创建结构的可变参数宏

我如何编写一个像这样使用的宏(用于 gcc):

CREATE_STRUCT(my_struct1,foo);
CREATE_STRUCT(my_struct2,foo,bar);
Run Code Online (Sandbox Code Playgroud)

并扩展到

struct my_struct1 {
     std::string foo;
};

struct my_struct2 {
     std::string foo;
     std::string bar;
};
Run Code Online (Sandbox Code Playgroud)

?

我当然需要不同数量的成员的灵活性,但对我来说已经很小的数量就可以了(比如 4 或 5)。

我发现了几个相关的问题,例如thisthis,但是在尝试将这种神秘的宏魔法应用于这个问题时,我完全迷失了。

PS:我知道如何编写 5 个宏(每个参数一个)来完成这项工作,所以实际上问题是:是否有一种“简单”的方法来编写一个可以完成这项工作的可变参数宏?另一方面,我将向结构中添加更多内容,因此将所有内容放在一个地方会节省大量样板。

c++ macros variadic-macros

5
推荐指数
1
解决办法
827
查看次数

是否可以在 C 编译时处理可变参数宏中的每个元素?

是否可以以某种方式归档以下内容?我正在使用 gcc。

#define foo(argCount, ...)\
    FOR_EACH_IN_VA_ARGS_(argCount, element, __VA_ARGS__)\
    {\
        printf("%u", sizeof(element));\
    }

Run Code Online (Sandbox Code Playgroud)

感谢您的回答。

c macros variadic-macros

5
推荐指数
1
解决办法
102
查看次数