- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的代码库已经包含重复的代码,只有细微的差别、可序列化的 ID、索引、变量数组。
代码库巨大,一些组件根据简单的预处理器指令和常量激活/停用(例如:#define CFG_PROJECT cfgAutobot
、#define CFG_PROJECT cfgUltron
、 ..等)。
功能实际上是相同的,但组件和条件不同。示例:
int somedata;
int somecounter;
void main_loop(){
#if(CFG_PROJECT == cfgAutobot)
if(someInterface() == 1){
somedata = some_other_interface();
}
#endif
#if(CFG_PROJECT == cfgUltron)
if(third_if() > 0){
someCounter++;
}
else
{
someCounter = 0;
}
#endif
}
void query_data(int selector){
if(False){
/* Dummy block */
}
#if(CFG_PROJECT == cfgUltron)
else if(selector == 1){
return somedata;
}
#endif
#if(CFG_PROJECT == cfgAutobot)
else if(selector == 2){
return someCounter;
}
#endif
else{
return Err_code;
}
}
由于此代码处理的数据比简单的计数器和整数要复杂得多,涉及不同大小的多个组件,因此这些代码部分要复杂得多。然而,它们可以追溯到一个共同的结构。
我能够应用 X-list 技术,如下所示:
#define Ultron_implementation X(var_ultron, (someInterface() == 1), update_function_1, selector_id_1)
#define Autobot_implementation X(var_autobot, (third_if() > 0), update_function_2, selector_id_2)
/* (Please note, that this is a simplified example, in the actual
code there are much more components, but the `main_loop`
implementation can be traced back to a few update functions) */
void update_function_1(int var, int selector) {
if(selector == 1){
var++;
}else{
var = 0;
}
}
void update_function_2(int var, int selector) {
if(selector == 1){
var = some_other_interface();
}else{
/* Nothing to do */
}
}
#define X(var_name,condition,func_name,sel_id) int var_name;
Ultron_implementation
Autobot_implementation
#undef X
void main_loop(){
#define X(var_name,condition,func_name,sel_id) \
if(condition){ \
func_name(var_name, true);\
}else{ \
func_name(var_name, false);\
}
Ultron_implementation
Autobot_implementation
#undef X
}
void query_data(int selector){
if(False){
/* Dummy block */
}
#define X(var_name,condition,func_name,sel_id) \
else if(selector == sel_id){ \
return var_name;\
}
Ultron_implementation
Autobot_implementation
#undef X
else{
return Err_code;
}
}
这样做的问题是,尽管现在是统一的实现,但新组件的引入仍然需要复制粘贴,并通过先前定义的常量进行过滤(即:CFG_PROJECT
) 现在已从逻辑中排除。
有没有一种方法可以最大限度地减少复制粘贴到代码中各个位置的需要并根据定义的常量(即CFG_PROJECT
)进行过滤?
最佳答案
在编译时过滤预定义常量需要预处理器指令#if
、#ifdef
等。但无法在内部使用这些指令#define
语句据我所知。
但是在 #define
语句之外编写这些内容是完全合法的。
#if(CFG_PROJECT == cfgAutobot)
#define Autobot_implementation X(var_autobot, (third_if() > 0), update_function_2, selector_id_1)
#else
#define Autobot_implementation
#endif
#if(CFG_PROJECT == cfgUltron)
#define Ultron_implementation X(var_autobot, (third_if() > 0), update_function_2, selector_id_2)
#else
#define Ultron_implementation
#endif
前者可以编译成一个列表(多种)
#define MACRO_LIST \
Autobot_implementation \
Ultron_implementation
根据定义的常量,MACRO_LIST
的元素将包含 X()
函数定义(即:实现)或空常量。
现在在实现中可以使用以下内容:
void main_loop(){
#define X(var_name,condition,func_name,sel_id) \
if(condition){ \
func_name(var_name, true);\
}else{ \
func_name(var_name, false);\
}
MACRO_LIST
#undef X
}
要总结已激活的组件,查看有多少组件被激活并在实现中引用它们,可以使用连接 (##
) 标记,例如枚举定义。示例:
#define X(var_name,condition,func_name,sel_id) var_name ## index,
tyepdef enum{
MACRO_LIST
components_end
}component_index;
#undef X
some_struct COMPONENT_FLAGS[components_end];
基本上任何相关的变量、ID 或实现都可以通过这种方式“序列化”。
此解决方案使代码更难理解、维护,并且确实难以调试,但一旦经过测试和验证,它就消除了复制粘贴带来的错误可能性。与替代方案相比,结果将是一个更干净、更优雅、更小的代码库。
它实际上将生产代码的开发时间从 3 个月缩短到了几个小时。
关于c - 使用 X 列表和预处理器指令在编译时生成可配置的 C 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39273219/
是否可以仅在点击 anchor 时为其分配 url? Token Link 当点击 anchor 时,它将转到 http://example.com/token=xxxxx/ 我只想在单击时生成 to
我不能 100% 确定我的错误。当我尝试生成 PDF 时,我得到了此编码输出: %PDF-1.4 %���� 3 0 obj <> /Contents 4 0 R>> endobj 4 0 obj <
下面的代码有几个函数,这些函数允许诸如将数据写入文档、读取文档以及将数据放入数组中以用于稍后的 JTable 等操作。 package tabletest.populatetable; import
我检查了我的网站 (WordPress) 应用程序的页面源并发现了以下内容 <iframe src="https://www.google.com/recaptcha
我有一个最终会生成 OutOfMemory 的程序。程序代码为: public class VeryLargeObject implements Serializable { public s
所以我正在构建一个博客引擎,它具有/articles/then-the-article-permalink 作为 URL 结构。我需要有 prev 和 next 链接,它们将通过 pub_date 跳
我有这个列表: string[] countries = { "USA", "CANADA" }; 当我运行这个查询时: query = (from user
我有一个将 InputStream 作为 InputStreamResource 返回的方法,当我让 swagger 生成文档时,它说返回类型是 InputStreamResource。如何更改此设置
令人惊讶的是,我找不到关于这个主题的任何内容。当在 EditText 中检测到“@”时,动态生成 ListView 的方法是什么。这是一个例子: 这是我目前所拥有的: textfield.setOn
我发现 Menhir 提供了 --dump 和 --explain 选项,它对调试有很大帮助。但是如何在 ocamlbuild 下启用这些选项,以便 Menhir 在编译时始终生成转储文件? 我尝试编
您好,我正在寻找使用 ajax 提交表单时在 codeigniter 中重新生成 csrf token 的过程。我希望在不刷新页面的情况下重新生成 token 。有没有办法做到这一点。 最佳答案 根据
int main(void) { float a; scanf("%f", &a); double c = sqrt(a); printf("%f", c);
我有看起来像这样的 Hibernate 实体(省略了 getter 和 setter): @Entity public class EntityA { @ManyToOne(fetch = F
我正在使用 git 来跟踪 wireshark project .我想提交一个补丁,但是所需的格式是以下输出(参见 http://www.wireshark.org/develop.html ): s
Spring 最近发布的关于在 Spring Boot 项目中使用静态 Web 内容的博文 (https://spring.io/blog/2013/12/19/serving-static-web-
我正在尝试设置我的测试环境,其中包括 React 测试库、Redux 工具包、RTK 查询和 TypeScript,但我遇到了一个我无法解决的问题。 我想不通的主要问题是如何生成 AppDispatc
我正在尝试将使用 Microsoft Access 数据库的网站移植到 MySQL。首先,我尝试打开 SQL 数据库: (旧)访问代码是: Set cn = Server.CreateObject (
我正在运行一个基本上从 Twitter 中提取推文的 Flask 应用程序。虽然使用嵌入式 Flask 服务器运行应用程序没有问题,但在 gUnicorn 中运行时我收到重复的推文,主要是因为我有 2
我正在学习 Python-这给了我一个 IO 错误- f = open('money.txt') while True: currentmoney = float(f.readline())
我想生成 N 个随机点,其乘积为某个值 1。 我在 MATALB 中是这样做的: N_=10; x1_=rand(1, N_); p_=prod(x1_); x_=x1_; x_(end)=x1_(e
我是一名优秀的程序员,十分优秀!