我想知道是否有办法将 C 预处理器用于这样的事情。我有一个包含大量SQL语句的代码,我想在启动时准备,然后只保留全局变量。我试图想出一种方法来编写一个可以转换的宏:
PREPARE_SQL (statement1_var, "SQL QUERY 1")
PREPARE_SQL (statement2_var, "SQL QUERY 2")
成:
static sqlite3_stmt * statement1_var;
static sqlite3_stmt * statement2_var;
static int prepare_statements(sqlite3 * db) {
int result;
result = sqlite3_prepare_v2(db, "SQL QUERY 1", -1, &statement1_var, NULL);
if (result != SQLITE_OK) {
return result;
}
result = sqlite3_prepare_v2(db, "SQL QUERY 2", -1, &statement2_var, NULL);
if (result != SQLITE_OK) {
return result;
}
return SQLITE_OK;
}
答案 0 :(得分:1)
使用X宏技术,首先使用尚未定义的宏PREPARE_SQL
定义列表#define LIST_OF_ENTRIES \
PREPARE_SQL (statement1_var, "SQL QUERY 1") \
PREPARE_SQL (statement2_var, "SQL QUERY 2")
然后定义PREPARE_SQL以声明变量,调用列表宏,然后再次取消定义PREPARE_SQL
#define PREPARE_SQL( var, text ) static sqlite3_stmt * var;
LIST_OF_ENTRIES // invoke the macro that contains the list
#undef PREPARE_SQL
然后,再次重新定义PREPARE_SQL,并调用相同的列表宏...
static int prepare_statements(sqlite3 * db) {
int result;
#define PREPARE_SQL(var, text) \
result = sqlite3_prepare_v2(db, text, -1, &var, NULL); \
if (result != SQLITE_OK) { \
return result; \
}
LIST_OF_ENTRIES // invoke the macro that contains the list
#undef PREPARE_SQL
return SQLITE_OK;
}
答案 1 :(得分:0)
这是一种方法。它需要两个宏,但我认为它接近你想要的。
宏:
#define PREPARE_SQL_DECLARATION(V) static sqlite3_stmt *(V);
#define PREPARE_SQL(V,Q) \
do { \
int result = sqlite3_prepare_v2(db, (Q), -1, &(V), NULL); \
if (result != SQLITE_OK) \
return result; \
} while(0);
宏的示例用法(例如source.c
)
PREPARE_SQL_DECLARATION(statement1_var);
PREPARE_SQL_DECLARATION(statement2_var);
PREPARE_SQL_DECLARATION(statement3_var);
static int prepare_statements(sqlite3 * db) {
PREPARE_SQL(statement1_var, "SQL QUERY 1");
PREPARE_SQL(statement2_var, "SQL QUERY 2");
PREPARE_SQL(statement3_var, "SQL QUERY 3");
return SQLITE_OK;
}
以下是宏扩展的输出(例如gcc -E source.c
)
static sqlite3_stmt *(statement1_var);;
static sqlite3_stmt *(statement2_var);;
static sqlite3_stmt *(statement3_var);;
static int prepare_statements(sqlite3 * db) {
do { int result = sqlite3_prepare_v2(db, ("SQL QUERY 1"), -1, &(statement1_var), 0); if (result != 0) return result; } while(0);;
do { int result = sqlite3_prepare_v2(db, ("SQL QUERY 2"), -1, &(statement2_var), 0); if (result != 0) return result; } while(0);;
do { int result = sqlite3_prepare_v2(db, ("SQL QUERY 3"), -1, &(statement3_var), 0); if (result != 0) return result; } while(0);;
return 0;
}
在宏中包装代码的do { ... } while (0);
是每个语句扩展和执行的一种方式,可以在范围内返回自己的int result
,但不会干扰后面的同名变量。< / p>
希望这有帮助。