为什么这个宏没有得到扩展?
Why is this macro not getting expanded?
这是 assets.cpp.i
的预处理器输出:
#define CLASSNAME GAMEOBJECT
#define CLASSNAME_NORMAL GameObject
#define GAMEOBJECT_EXPANSION(FUNC) FUNC(std::vector<std::shared_ptr<Component>>, comps)
# 1 "/home/rubend/p/engine/libs/include/prefab.h" 1
#define prefab_h
#define PREFAB_VAR_ENUM_NAME(name) name ##_enum
#define PREFAB_VAR_ENUM_DIRTY(type,name) PREFAB_VAR_ENUM_NAME(name),
# 42 "/home/rubend/p/engine/libs/include/prefab.h"
#define _CLASSNAME_EXPANSION(classname,func) classname ## _EXPANSION(func)
#define CLASSNAME_EXPANSION(func) _CLASSNAME_EXPANSION(CLASSNAME,func)
template<class T>
class Prefab:public File{
private:
std::shared_ptr<T> ref;
protected:
enum DIRTY_ENUM{First, CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY) Last};
};
现在为什么 CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY)
根本没有展开?
串联标记有什么我不知道的特别之处吗?
我正在使用 GCC 9.3 和 CMake 3.16.5
回答
通过添加另一个宏修复了它:
#define __CLASSNAME_EXPANSION(classname, func) classname ## _EXPANSION(func)
#define _CLASSNAME_EXPANSION(classname, func) __CLASSNAME_EXPANSION(classname,func)
#define CLASSNAME_EXPANSION(func) _CLASSNAME_EXPANSION(CLASSNAME,func)
更新 12/4/20
@rici 指出我应该把下划线放在最后,因为内部库宏在开头使用它们。
如果您关注扩展,您会注意到 CLASSNAME_EXPANSION 正在扩展到自身。
让我们一步一步来看看发生了什么:
CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY)
-> _CLASSNAME_EXPANSION(CLASSNAME,PREFAB_VAR_ENUM_DIRTY)
-> CLASSNAME ## _EXPANSION(PREFAB_VAR_ENUM_DIRTY)
-> CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY)
并且由于这个宏的名称与原始名称相同(即它是一个嵌套名称)我们不扩展它。
这是 assets.cpp.i
的预处理器输出:
#define CLASSNAME GAMEOBJECT
#define CLASSNAME_NORMAL GameObject
#define GAMEOBJECT_EXPANSION(FUNC) FUNC(std::vector<std::shared_ptr<Component>>, comps)
# 1 "/home/rubend/p/engine/libs/include/prefab.h" 1
#define prefab_h
#define PREFAB_VAR_ENUM_NAME(name) name ##_enum
#define PREFAB_VAR_ENUM_DIRTY(type,name) PREFAB_VAR_ENUM_NAME(name),
# 42 "/home/rubend/p/engine/libs/include/prefab.h"
#define _CLASSNAME_EXPANSION(classname,func) classname ## _EXPANSION(func)
#define CLASSNAME_EXPANSION(func) _CLASSNAME_EXPANSION(CLASSNAME,func)
template<class T>
class Prefab:public File{
private:
std::shared_ptr<T> ref;
protected:
enum DIRTY_ENUM{First, CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY) Last};
};
现在为什么 CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY)
根本没有展开?
串联标记有什么我不知道的特别之处吗?
我正在使用 GCC 9.3 和 CMake 3.16.5
回答
通过添加另一个宏修复了它:
#define __CLASSNAME_EXPANSION(classname, func) classname ## _EXPANSION(func)
#define _CLASSNAME_EXPANSION(classname, func) __CLASSNAME_EXPANSION(classname,func)
#define CLASSNAME_EXPANSION(func) _CLASSNAME_EXPANSION(CLASSNAME,func)
更新 12/4/20
@rici 指出我应该把下划线放在最后,因为内部库宏在开头使用它们。
如果您关注扩展,您会注意到 CLASSNAME_EXPANSION 正在扩展到自身。
让我们一步一步来看看发生了什么:
CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY)
-> _CLASSNAME_EXPANSION(CLASSNAME,PREFAB_VAR_ENUM_DIRTY)
-> CLASSNAME ## _EXPANSION(PREFAB_VAR_ENUM_DIRTY)
-> CLASSNAME_EXPANSION(PREFAB_VAR_ENUM_DIRTY)
并且由于这个宏的名称与原始名称相同(即它是一个嵌套名称)我们不扩展它。