Urv*_*viG 1 c macros structure
有一个C结构
struct a
{
int val1,val2;
}
Run Code Online (Sandbox Code Playgroud)
我已经对代码进行了更改
struct b
{
int val2;
}
struct a
{
int val1;
struct b b_obj;
}
Run Code Online (Sandbox Code Playgroud)
现在,在其他C文件中使用val2就像a_obj->val2;.
我想替换它的声明用法,并且它们有很多,所以我在头文件中定义了一个宏,其中struct a定义如下:
#define a_obj->val2 (a_obj->b_obj.val2)
Run Code Online (Sandbox Code Playgroud)
它不起作用.->在宏定义的标识符部分是非法的#define吗?
有人可以告诉我我哪里错了吗?
根据@Basile的建议进行编辑 -
这是一个遗留源代码,一个非常庞大的项目.不确定LOC.
我想做出这样的改变,因为我想让它更模块化.
例如,我想在相同的名称下对结构的类似字段进行分组,这就是我想要创建另一个结构B的原因,该结构B的字段与B功能相关并且也与A共用.
我不能使用其他的查找替换功能文本编辑,我正在使用VIM.
这种宏观魔法很快就会让你陷入困境,
因为它使你的源代码变得难以理解和脆弱(因为措辞而言是卑鄙的).
但这应该适用于你描述的内容.
struct b
{
int val2m;
}
struct a
{
int val1;
struct b b_obj;
}
#define val2 b_obj.val2m
Run Code Online (Sandbox Code Playgroud)
诀窍是给结构声明中的实际标识符一个新的名称(val2m),以便所有其他代码使用的名称可以转换为魔术别名,
然后可以包含修改后的访问权限,通过另外引入的绕道内部结构.
这只是一种带状辅助,用于解决现有代码中后台更多内容的问题.只有在没有机会彻底重构代码时才使用它.("创可贴",故事讲述者的合适形象,学分).
我明确建议查看Basiles答案,以获得更清洁,更"面向未来"的方式.这是避免我使用这个宏魔法预测的麻烦的方法.如果您没有被非常充分的理由强迫使用它.
正如其他人所解释的,预处理器仅适用于令牌,并且您只能#define使用名称。阅读C11 标准n1570的文档cpp。
你想做的事情很丑陋(而且很少有值得这样做的场合)。它使您的代码变得凌乱、不可读和脆弱。
学习更好地使用您的源代码编辑器(您可能有一些交互式替换,或使用 regexp-s 进行交互式替换;如果没有,请切换到更好的编辑器,如GNU emacs或vim- 并研究您的编辑器的文档)。你也可以使用脚本工具,如ed,sed,grep,awk等...帮助你在做这些替代品。
在一个小项目,更换相关的事件->val2(或.val2有)->b_obj.val2(或.b_obj.val2)是很容易的,即使你对他们有一百个。这使您的代码保持可读性。不要忘记使用一些版本控制系统(以保留代码的旧版本和新版本)。
在至少有一百万行源代码的大型项目中,您可能会问如何找到val2给定类型的每次出现的字段用法(但您可能应该命名val2得足够好以使它的大多数出现是相关的;在其他话,注意字段的命名)。这是一个非常不同的问题(例如,您可以编写一些GCC 插件来查找此类事件并帮助您替换相关的事件)。
如果您正在重构旧的大型遗留代码,您需要确保保持其可读性,并且您不想要花哨的宏技巧。例如,您可以添加一些static inline函数来访问该字段。然后使用一些更好的工具(例如编译器插件、某种 C 解析器等)来帮助您进行重构可能是值得的。
保持源代码对人类开发人员可读。否则,你就是在用脚射击自己。你想做的是不合理的,它降低了代码库的可读性。
我不能使用其他文本编辑器的查找替换功能,我使用的是 VIM。
vim可编写脚本(例如 in lua)并接受插件(因此如果交互式替换还不够,请考虑编写一些vim插件或脚本来帮助您),并且具有强大的查找替换正则表达式功能。您也可以使用一些脚本组合来帮助您。在许多情况下,它们就足够了。如果不是,您应该解释原因。
此外,您可以临时用一个唯一的名称(或任何合适的名称,制作一些独特的“随机外观”名称很容易)来临时替换val2字段。然后你运行你的完整构建(例如在 some 之后)。编译器将为您需要替换用作字段的每个位置发出错误消息(但不介意用于其他目的的名称的任何其他出现)。这会对您有很大帮助 - 一旦您更正了代码以消除所有错误 - (尤其是与某些编辑器脚本结合使用时),因为那时您只需要替换为任何地方。struct aval2_3TYRxW1PuK7make cleanval2struct aval2val2_3TYRxW1PuK7b_obj.val2