典型的C与C预处理器重构

典型的C与C预处理器重构,c,refactoring,C,Refactoring,我正在开发一个支持预处理器的C重构工具。。。 我不知道大型C项目中涉及到什么样的重构,我想知道人们在重构C代码(和预处理器指令)时实际做了什么 我还想知道是否有一些真正有趣的特性没有出现在任何工具中,因此重构必须完全手动完成。。。例如,我看到Xref无法重构用作迭代器的宏(但我不知道这到底意味着什么) 谢谢,我会告诉你,没有什么好的工具来重构C++,就像java一样。大部分搜索和替换都是痛苦的,但这取决于实际任务。看看NETBeaS和Eclipse C++插件。 例如,我看到外部参照可以 不重构

我正在开发一个支持预处理器的C重构工具。。。 我不知道大型C项目中涉及到什么样的重构,我想知道人们在重构C代码(和预处理器指令)时实际做了什么

我还想知道是否有一些真正有趣的特性没有出现在任何工具中,因此重构必须完全手动完成。。。例如,我看到Xref无法重构用作迭代器的宏(但我不知道这到底意味着什么)


<>谢谢,<>我会告诉你,没有什么好的工具来重构C++,就像java一样。大部分搜索和替换都是痛苦的,但这取决于实际任务。看看NETBeaS和Eclipse C++插件。 例如,我看到外部参照可以 不重构用作 迭代器(不知道具体是什么 这意味着(尽管如此)

老实说,你可能在你的脑子里——考虑一下你是否是这个任务的合适人选。< /P> < P >巨大的话题!
  • 我需要清理的是扭曲的
    #ifdefs
    巢穴。重构工具可以理解参数列表(函数声明或定义)中何时出现条件内容,并对此进行改进

  • 如果它真的很好,它会意识到这一点

    #if defined(SysA) || defined(SysB) || ... || defined(SysJ)
    
    实际上相当于:

    #if !defined(SysK) && !defined(SysL)
    
    如果你做到了,我会很惊讶的

  • 它允许我指定“这个宏现在已定义-哪个代码是可见的”(意思是对编译器可见);它还允许我选择查看不可见的代码

  • 它将处理一个跨越100多个顶级目录的系统,这些目录下有不同级别的子目录。它将处理数以万计的文件,每个位置的长度为20K行

  • 它将标识宏定义来自makefile而不是头文件的位置(aargh!)


宏通常会变得非常复杂,因此我不会尝试支持比简单重命名更多的功能。

如果您能够在具有任意复杂目录层次结构的大型项目上处理各种类型、变量和宏的可靠重命名,我想使用您的产品。

,因为它是预处理器的一部分#包括重构是一个巨大的主题,我不知道有什么工具能真正做到这一点

工具可以解决的小问题:

  • 在#includes中强制使用一致的大小写和反斜杠
  • 强制执行一致的标头保护约定,自动添加冗余外部保护等
工具可以解决的更难的问题:

  • 查找和消除杂散包括
  • 建议在可行的情况下使用预折旧
对于宏。。。也许某种范围界定会很有趣,如果在块内定义宏,工具会在块的末尾自动取消定义宏。我能想到的其他快速的事情:

  • 快速分析宏观安全性可能会有所帮助,因为许多人仍然不知道如何使用do{}while(0)和其他技术
  • 或者,查找并标记带有副作用的表达式作为宏参数传递的位置。这可能真的对一些事情很有帮助,比如。。。具有非故意副作用的断言

    • 任何对此感兴趣的人(特定于C),都可能想看看:

      Coccinelle是一个程序匹配和转换引擎,它提供了语言SmPL(语义修补语言),用于在C代码中指定所需的匹配和转换。Coccinelle最初的目标是在Linux中执行并行进化。此类演进包括响应库API中的演进而在客户端代码中需要的更改,并且可能包括修改,例如重命名函数、添加其值在某种程度上依赖于上下文的函数参数以及重新组织数据结构。除了并行进化之外,Coccinelle还被(我们和其他人)成功地用于发现和修复系统代码中的bug


      刚刚发现了这个老问题,但我想说的是,我已经为C解救了免费版本的Xrefactory,现在命名为,它可以在宏中进行一些重构,例如重命名宏、重命名宏参数。

      不,我是说C预处理器…我太专注于此了…对不起:-)Oops。。。对不起,我把问题搞砸了。没问题…你有一个好的意图…-)不劳无获…cpp很直率,但你必须支持它并找到处理它的方法…这是我的工作…:-)这是一个巨大的话题我知道。。。命令行宏非常糟糕…:-)。。。宏之间的互斥是不可能实现的,我想,因为你不知道你拥有的选项集是什么…我一直在研究linux内核中的Kconfig语言…使用这种东西可以实现这个目的。。。感谢您使用软件再工程工具包。它被用于的许多任务之一是简化预处理器条件;请参见同一网站上关于此主题的论文。如果不添加额外的规则,您的示例很难做到(它从哪里知道只有L个互斥开关?),但实际上您可以添加该规则。它可以满足您的所有要求,并通过应用于3500万行C代码的系统得到了验证。@Ira Baxter:谢谢您提供的信息。请注意,注释不接受HTML锚定符号-因此,当单击链接时,链接会显示为半截,因为网站不识别结尾处的“
      ”>DMS
      ”。我意识到这个#包含问题…我已经在研究这个问题…你说的预声明是什么意思?我在分析时考虑过这个问题(如果宏定义的末尾有“;”的话…)副作用很难…thx…预声明,我的意思是…人们通常通过包含标题来获得结构定义