我正在使用第三方开源应用程序执行我认为很奇怪的事情。我想听听你对你是否认为这是错误/邪恶/憎恶/等的看法,或者是否有合理的理由这样做。
简单地说,他们使用#include pre-proc指令来包含包含代码片段的“头文件”。不是函数的原型。不是内联功能。只是代码的一部分。
这是一个简单的例子。首先是main.cpp文件:
#include <iostream>
//Other "normal" includes here...
int main(int argc, char *argv[]) {
cout << "Initializing program..." << endl;
#include "parseArgs.h"
// ... remainder of the program
cout << "Exiting." << endl;
return 0;
}
在parseArgs.h头文件中,有一个小代码片段。请注意,这只是parseArgs.h文件中的内容。这不是功能的一部分。没有包括警卫,只有以下4行:
argList args(argc, argv);
if(!args.valid()) {
cout << "Invalid arguments.";
exit(1);
}
在真实的程序中,有几个#include指令,每个指令执行另一项小任务。
这似乎是危险和疯狂的。我不知道他们为什么不写作并将其称为函数。
您的想法和意见?
答案 0 :(得分:8)
我想你在这里谈论OpenFOAM。这些代码片段解决的问题是避免了OpenFOAM中许多应用程序需要的样板代码的重复。将此代码放在函数中将无法解决问题,因为函数内声明的变量是其作用域的局部变量。或许可以想出一个包含这些变量作为成员的基类方案。但这只会添加另一层间接,并不能真正解决任何问题。你仍然依赖于变量名(或者,如果你想让它变得干净,那就是getter-names)。
就个人而言,我不确定这种做法是好还是坏。它是如何,它是OpenFOAM代码文化的一部分(或本地语言,如果你想)。乍一看,这是令人惊讶的,但人们很快习惯它。
但是,除非您自己开发OpenFOAM应用程序/扩展,否则我强烈反对这种做法。 OpenFOAM有点独特之处在于它包含几乎数百个可执行文件,这些可执行文件都需要一些难以维护的重叠样板代码。如果你不是那种情况,那就不要这样做。
答案 1 :(得分:0)
我会毫不犹豫地称之为“疯狂”,因为可能有这种#include
用法的原因。问题是了解这些原因并判断这是否是给定环境中的最佳方法。我可以想象的原因是,代码是以某种方式生成的,而不是手写的。
答案 2 :(得分:0)
我认为这非常混乱,你会更好地编写一个函数。
这是我在SO上发现的一个问题"Why it's valid to include a header file twice in c++?" 您可能会发现答案很有趣,我绝不会以这种方式编写代码,因为我认为修复错误和任何其他问题会非常痛苦和耗时
答案 3 :(得分:0)
我不会把那种事情称为“疯狂” - 我会使用“不寻常”,“难以理解”,“意外”等术语,因此“难以阅读,调试和维护”。或者只是“WTF” - decreasing code quality。
永远不要那样做。使用功能。或者如果真的,真的必须使用一个完全相同但人们更熟悉的宏。是的,宏是坏的,并且在调试时可以成为一个皮塔饼。但这更糟糕。
编辑澄清:我不喜欢宏。尽可能避免使用它们。大多。使用功能,模板,任何东西。但是当它归结为“宏或WTF - #include
”时,请使用宏。
答案 4 :(得分:0)
如果您在团队中工作,则需要制定程序和标准以确保沟通顺畅。一旦解决了,你说葡萄牙语还是普通话都无所谓,只要每个人都觉得舒服就行。
这是一个心态问题。有些人——包括和我一起工作的老师——被规则奴役;但是,我不能认真对待它们,特别是当其中一个为了教授面向对象而使用“生菜”和“水果”作为示例时。我怀疑科尔伯格的阶段有点拖慢了某些人的思考速度。
我在个人项目中使用这种技术 - 包括 source.cpp。我已经在 C 和 Lazarus (Pascal) 中完成了它,它比摆弄链接器参数和 makefile 更适合我的目的。我的代码有注释,变量声明对齐,赋值运算符也对齐,当学生给我代码时,我会遍历所有代码,插入空格和行,直到它看起来像我喜欢的样子,然后再分析它。我沉迷于干净的源代码组织。你看?疯狂有方法!
工具(#include、#define、lambda...)就是:工具,当然,意外使用工具可能会让人迷失方向; 那很糟糕。更重要的是,当“软件的心理复杂性”(谷歌它)伤害到(你或你团队中的某个人)时,立即停止并仔细研究出了什么问题。
这是我的 2cts。