gpt4 book ai didi

c - 编写函数原型(prototype)的明智方法

转载 作者:太空狗 更新时间:2023-10-29 15:26:37 25 4
gpt4 key购买 nike

我正在寻找一种(干净的)方法来编写函数定义和函数原型(prototype),而无需代码重复。由于 DRY 已被确立为一个好主意,并且在头文件中手动编码原型(prototype)是一种明显的违规行为,因此这似乎是一个合理的要求。

下面的示例代码指出了使用预处理器解决问题的(粗略的)方法。它似乎不太可能是最佳的,但似乎确实可以正常工作。

使用单独的文件和复制:

foo.h:
#ifndef FOO_H
#define FOO_H
// Normal header file stuff
int dofoo(int a);
#endif /* FOO_H */

foo.c:
#include "foo.h"
int dofoo(int a) {
return a * 2;
}

使用 C 预处理器:

foo.h:
#ifndef FOO_H
#define FOO_H

// Normal header file stuff

#ifdef PROTOTYPE // if incorrect:
// No consequences for this test case, but we lose a sanity check
#error "PROTOTYPE set elsewhere, include mechanism will fall over"
#endif

#define PROTOTYPE // if incorrect:
// "error: redefinition of 'dofoo'" in clang & gcc,
// referring to int dofoo() line in foo.c
#include "foo.c"
#undef PROTOTYPE //if incorrect:
// No warnings, but should trigger the earlier #error statement if
// this method is used in more than one file

#endif /* FOO_H */

foo.c:
#include "foo.h"

int dofoo (int a)
#ifdef PROTOTYPE // if incorrect:
// "error: redefinition of 'dofoo'" in clang & gcc,
// referring to int dofoo() line in foo.c
;
#else
{
return a * 2;
}
#endif

该机制有点奇怪 - .h 文件通常不包含 .c 文件! include 守卫停止递归。当通过独立的预处理器运行时,它编译干净并且看起来合理。否则,在整个源代码中嵌入预处理器条件看起来不太好。

我可以想到几种替代方法。

  1. 不用担心代码重复
  2. 更改为自动生成界面的语言
  3. 使用代码生成器(例如 sqlite 的 makeheaders)

代码生成器可以工作,但作为一个小烦恼的解决方案似乎有点过分了。由于此时 C 已经存在超过 25 年,因此希望社区就最佳路径达成共识。

感谢阅读。

编辑:gcc 4.8.2 和 clang 5.1 的编译器警告弄乱宏语句会产生相当连贯的编译器错误消息。缺少#endif(如果函数定义很长,很容易做到)会产生“错误:未终止的#else”或“错误:未终止的条件指令”,两者都指的是#ifdef 行。

缺少#else 意味着代码不再有效 C.gcc“错误:预期标识符或'('在'{'标记之前”并且clang添加“函数声明符之后的预期函数体”。两者都指向正确的行号,但都没有暗示缺少#else。

如果结果是致命的,拼写错误的 PROTOTYPE 会产生连贯的消息,如果结果无关紧要,则不会发出警告。当定义和声明不同时,编译器警告并不像它们可能的那样具体,但它们可能足够具体。

最佳答案

普遍接受的路径是您的选项 1),不用担心,只需将声明写两次即可。

与函数实现相比,来自原型(prototype)的重复只是一小部分。像您问题中的宏黑客很快变得笨拙并且几乎没有 yield 。宏机制最终与原始原型(prototype)一样多的代码,只是现在更难理解正在发生的事情,而且您会收到更多神秘的错误消息。理解重复的微不足道被大约相同数量的难以理解的诡计所取代。

对于普通的原型(prototype),编译器会在事情不匹配时发出警告,对于这样的宏基础解决方案,如果您忘记了 #endif 或其他不匹配的东西,您将很难理解错误配对。例如,错误中提及的任何 foo.c 可能有或没有定义 PROTOTYPE

关于c - 编写函数原型(prototype)的明智方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24142902/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com