我正在利用C++全局变量的构造函数的行为以简单的方式在启动时运行代码.这是一个非常简单的概念,但有点难以解释,所以让我只需粘贴代码:
struct _LuaVariableRegistration
{
template<class T>
_LuaVariableRegistration(const char* lua_name, const T& c_name) {
/* ... This code will be ran at startup; it temporarily saves lua_name and c_name in a std::map and when Lua is loaded it will register all temporarily global variables in Lua. */
}
};
Run Code Online (Sandbox Code Playgroud)
然而,每次想要注册Lua全局变量时手动实例化那个超级丑陋的类是很麻烦的; 这就是我创建以下宏的原因:
#define LUA_GLOBAL(lua_name, c_name) static Snow::_LuaVariableRegistration _____LuaGlobal ## c_name (lua_name, c_name);
Run Code Online (Sandbox Code Playgroud)
所以你要做的就是把它放在cpp文件的全局范围内,一切都很完美:
LUA_GLOBAL("LuaIsCool", true);
Run Code Online (Sandbox Code Playgroud)
你去!现在在Lua LuaIsCool中将变量初始化为true!
但是,问题在于:
LUA_GLOBAL("ACCESS_NONE", Access::None);
Run Code Online (Sandbox Code Playgroud)
哪个成了:
static Snow::_LuaVariableRegistration _____LuaGlobalAccess::None ("ACCESS_NONE", &Access::None);
Run Code Online (Sandbox Code Playgroud)
:((我需要c_name在宏中连接或者它会抱怨两个具有相同名称的变量;我尝试用它替换它__LINE__但它实际上变成了 …
我有
#define A_T 1
#define B_T 2
int x_a = 1, x_b =2;
Run Code Online (Sandbox Code Playgroud)
如何定义一个宏,它可以将后缀_a和_b连接到var名称?
for example, something like this
#define A_T_SUF _a
#define B_t_SUF _b
#define SUFFIX(t) t ## _SUF
#define VAR_SUF(var, t) var ## SUFFIX(t)
.....
VAR_SUF(x, A_T) ---> be replaced to x_a
Run Code Online (Sandbox Code Playgroud)
这可能吗?
我无法正确使用这个宏扩展
#define foo Hello
#ifdef foo
#define wrapper(x) foo ## x
#else
#define wrapper(x) boo ## x
#endif
Run Code Online (Sandbox Code Playgroud)
电话:
wrapper(_world)
Run Code Online (Sandbox Code Playgroud)
我想结果
Hello_world
Run Code Online (Sandbox Code Playgroud)
然而,宏正在将"foo"定义为文字,从而给予
foo_world
Run Code Online (Sandbox Code Playgroud)
有人可以指出我的错误吗?
谢谢
我知道这个问题有一个C++版本,但是我使用的是标准的typedef而不是模板.
我编写了一个适用于16位wav文件的程序.它通过将每个样品加载到一个短片中来实现.然后程序在短路上执行算术运算.
我现在正在修改程序,因此可以同时使用16位和32位的wav.我希望做一个条件typedef,即使用16位的short和32位的int.但后来我意识到如果事先不知道变量的类型,编译器可能不会编译代码.
所以我试着测试下面的代码:
#include <stdio.h>
int
main()
{
int i;
scanf("%i", &i);
typedef short test;
if(i == 1)
typedef short sample;
else
typedef int sample;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并得到以下编译器错误:
dt.c: In function ‘main’:
dt.c:12:5: error: expected expression before ‘typedef’
dt.c:14:5: error: expected expression before ‘typedef’
Run Code Online (Sandbox Code Playgroud)
这是否意味着C中的运行时条件typedef不可能?
[开放式问题:]如果没有,你们将如何处理这样的事情?
我已经定义了一个类似对象的宏和一个类似函数的宏(来自这个问题).
#define SYSTEM windows
#define CALL(function, ...) (function)(__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
鉴于这个定义,CALL(foo, arg1, arg2)变成了foo(arg1, arg2).
我想CALL(foo, args)变成x__foo(args),x无论SYSTEM被定义为什么.
我试过了:
#define CALL(function, ...) SYSTEM##__function(__VA_ARGS__)
#define CALL(function, ...) (SYSTEM)##__##(function)(__VA_ARGS__)
#define CALL(function, ...) ((SYSTEM)##__##(function)(__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
它们都会导致编译器错误.
我如何定义CALL,使其串接的值SYSTEM,__和值function?
我正在尝试创建一个sscanf字符串文字,以帮助在C99中防止缓冲区溢出.目标是这样的:
#define MAX_ARG_LEN 16
char arg[MAX_ARG_LEN] = "";
if (sscanf(arg, "%"(MAX_ARG_LEN-1)"X", &input) > 0)
Run Code Online (Sandbox Code Playgroud)
显而易见的"手动"解决方案如下:
#define MAX_ARG_LEN 16
#define MAX_ARG_CHARS "15"
char arg[MAX_ARG_LEN] = "";
if (sscanf(arg, "%"MAX_ARG_CHARS"X", &input) > 0)
Run Code Online (Sandbox Code Playgroud)
但是,我希望在缓冲区大小为16的情况下自动生成"%15X".这个链接几乎适用于我的应用程序:将预处理程序标记转换为字符串,但它不处理-1.
建议?
#define LINK_ENTITY_TO_CLASS(mapClassName,DLLClassName) \
static CEntityFactory<DLLClassName> mapClassName( #mapClassName );
Run Code Online (Sandbox Code Playgroud)
这是来自Alien Swarm mod for Half-Life 2的一个宏,意在用MSVC编译.
我以前从来没有见过#一个宏之前的参数,我不确定这是一个特定的MSVC还是不常见.这是什么意思?
我把我的问题提炼到这个代码片段 - 但它是一个更大的程序的一部分,所以我不想要一个不同的方式来做到这一点 - 我需要一种方法来使这项工作!
当我从这段代码生成预处理文件时:
#define OUTER(a, b) \
a##b
#define INNER(c, d) \
c##d
enum foo {
OUTER(INNER(x, y), z)
}; // line 108
int APIENTRY _tWinMain(...)
{
foo bar = xyz; // line 112
}
Run Code Online (Sandbox Code Playgroud)
我明白了:
enum foo {
xyz
}; // line 108
int __stdcall wWinMain(...)
{
foo bar = xyz; // line 112
}
Run Code Online (Sandbox Code Playgroud)
这就是我想要的.但是,如果我尝试编译代码,我得到:
错误C2146:语法错误:在标识符'z'之前缺少'}'第108行
错误C2143:语法错误:缺少';' 在'}'第108行之前
错误C2143:语法错误:缺少';' 在'}'第108行之前
错误C2059:语法错误:'}'第108行
错误C2065:'xyz':未声明的标识符行112
我无法解决这个问题!问题似乎是由于##:
#define OUTER(a, b) \
a##b
Run Code Online (Sandbox Code Playgroud)
但是为什么(以及如何解决它)超出了我......
我知道多Q&作为[的1,2 ]是紧密联系在这个问题上,我一直试图实现他们的解决方案,但事实证明,我需要使用.在我的连接中似乎给我带来了麻烦.
这就是我要的:
#include <stdio.h>
#define PROPERTY .value1
#define MAKE_PROP(var) var##PROPERTY
typedef struct {
int value1;
int value2;
} Node;
int main(void) {
Node node;
node.value1 = 1;
node.value2 = 2;
// MAKE_PROP(node) should evaluate to "node.value1".
printf("%d", MAKE_PROP(node));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然而它给了我各种各样的错误.如果我尝试[ 2 ]中的PASTER-EVALUATE想法,那么它会告诉我"粘贴"."和"PROPERTY"没有给出有效的预处理令牌".
谁知道如何完成我需要的东西?它必须保持一般,并且我可以使用,var因为这是我想在不同的变量名称上多次调用的东西.
我正在尝试建立一个测试,以检查某个文件是否定义了具有某个名称空间的标头保护。由于测试是通用的,因此仅在编译时才知道此名称空间,并以形式传入-DTHENAMESPACE=BLA。然后,我们使用/sf/answers/104298981/的一些魔术将它们粘贴在一起。
这意味着我想做类似的事情:
#define PASTER(x, y) x##_##y
#define EVALUATOR(x, y) PASTER(x, y)
#define NAMESPACE(fun) EVALUATOR(THENAMESPACE, fun)
#ifndef NAMESPACE(API_H) // evaluates to BLA_API_H
# error "namespace not properly defined"
#endif
Run Code Online (Sandbox Code Playgroud)
但这不能正常工作,因为cpp抱怨ifndef括号不正确。
如果有可能,我该如何正确地做到这一点?
我也尝试过添加更多的间接层,但是没有取得很大的成功。
因此,直接执行#ifdef此操作至少似乎是不可能的:
考虑到defined运营商:
如果定义的运算符是由于宏扩展而出现的,则C标准表示该行为是undefined。GNU cpp将其视为真正的定义运算符,并对其进行正常评估。如果您使用命令行选项-Wpedantic,它将在您的代码使用此功能的任何地方发出警告,因为其他编译器可能会以不同方式处理它。该警告也可以通过-Wextra启用,也可以通过-Wexpansion-to-defined单独启用。
https://gcc.gnu.org/onlinedocs/cpp/Defined.html#Defined
并ifdef预期会出现MACRO,并且不会进一步扩展。
https://gcc.gnu.org/onlinedocs/cpp/Ifdef.html#Ifdef
但是也许有可能触发“未定义的常量”警告(-Wundef),这也将使我的测试管道能够解决此问题。
假设有标志定义,例如:
SHF_WRITE 0x1
SHF_ALLOC 0x2
SHF_EXECINSTR 0x4
SHF_MASKPROC 0xf0000000
Run Code Online (Sandbox Code Playgroud)
给定一个标志,我需要输出SHF_WRITE|SHF_ALLOC比特0x1并0x2打开.
怎么用C做的伎俩?
我试图弄清楚如何编写一个宏,将一个变量的值附加到字符串.这是一个非工作代码的片段,但我正在展示它,以便我可以解释我想要做什么
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define DATA_RESPONCE_0 23
#define DATA_RESPONCE_1 24
#define DATA_RESPONCE_2 25
#define DATA_RESPONCE_3 26
#define my_macro(x) DATA_RESPONCE_##x
int main() {
int i = 0;
int k;
k = my_macro (i);
cout << k;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,宏被扩展为DATA_RESPONCE_i,但我希望它是DATA_RESPONCE_0,因此23应该打印为k的值.