C 什么';在不同的头文件中定义参数的用途是什么?

C 什么';在不同的头文件中定义参数的用途是什么?,c,coding-style,C,Coding Style,所以我一直在看一些代码,有些事情我不明白。 我有两个头文件。其中一种称为“args.h”,其中包括以下语句: #if (defined(__cplusplus) || defined(__STDC__) || defined(c_plusplus)) #define NEW_STYLE 1 #define VOID void #define ARGS(parenthesized_list) parenthesized_list #else #define NEW_STYLE 0 #defi

所以我一直在看一些代码,有些事情我不明白。 我有两个头文件。其中一种称为“args.h”,其中包括以下语句:

#if (defined(__cplusplus) || defined(__STDC__) || defined(c_plusplus))
#define NEW_STYLE 1
#define VOID    void
#define ARGS(parenthesized_list) parenthesized_list
#else
#define NEW_STYLE 0
#define VOID
#define ARGS(parenthesized_list) ()
#define const
#endif

#if !defined(EXIT_SUCCESS)
#define EXIT_SUCCESS    0
#define EXIT_FAILURE    1
#endif
在另一个头文件中,函数原型声明如下:

#if defined(__cplusplus)
extern "C" {
#endif

extern void     yyerror ARGS((const char *s_));
extern int      yylex ARGS((void));
extern int      yyparse ARGS((void));
extern int      yywrap ARGS((void));

#if defined(__cplusplus)
}
#endif
还有一堆其他的东西

因此,我的问题是:

1> #define const到底做什么

2> 为什么在另一个头文件中声明arg?难道我们不能简单地像普通的外部void a(const char*s_uuu)那样声明函数吗?或者这仅仅是一种风格偏好


谢谢。

这是为了让代码可以用标准C编译器编译。它将函数原型转换为函数声明,并完全删除
const

如果您需要使用一个非常古老的编译器,以致于它不理解原型或常量,那么除了使用这样的编译器外,您别无选择。否则,你最好把这些可怕的乱七八糟的东西去掉


20年前,像这样的代码很常见,也是必要的。现在似乎很难原谅,但我想可能仍然有一些平台没有一个合理的现代编译器。

这是为了允许代码用一个标准前C编译器编译。它将函数原型转换为函数声明,并完全删除
const

如果您需要使用一个非常古老的编译器,以致于它不理解原型或常量,那么除了使用这样的编译器外,您别无选择。否则,你最好把这些可怕的乱七八糟的东西去掉


20年前,像这样的代码很常见,也是必要的。现在似乎很难原谅,但我想可能仍然有一些平台没有一个合理的现代编译器。

这些都是一些调整,可以使代码在缺少这个或那个功能的编译器之间进行移植

  • 正在到处删除常量(如果您有一个现代编译器,这肯定不是一个好主意)
  • 这是因为

  • 这些都是为了使代码在缺少这个或那个特性的编译器之间可移植而做的调整

  • 正在到处删除常量(如果您有一个现代编译器,这肯定不是一个好主意)
  • 这是因为

  • 哎哟,我希望
    const
    在那之后得到
    #undef
    编辑。我会立即认为args可能在其他地方使用,并且由于依赖性的原因,文件是分开的。无论采用哪种方法,如果有具有相同参数列表的函数族,则必须是一种特殊情况。你能举个真实的例子吗?是的,以后它还没有定义。我所指的具体案例是一个lex文件,其中这两个文件被用作lex文件的头。哎哟,我希望
    const
    gets
    #unde
    ed之后。我会立即认为args可能被用在其他地方,并且由于依赖性的原因,该文件是分开的。无论采用哪种方法,如果有具有相同参数列表的函数族,则必须是一种特殊情况。你能举个真实的例子吗?是的,以后它还没有定义。我所指的具体案例是一个lex文件,其中这两个文件被用作lex文件的头。“像这样的代码是常见的”它是否如此常见以至于不值得评论,或者至少是
    \ifndef\uu STDC\uuuuu VERSION\uuuuu
    ?或者我们可以有把握地说作者是个流氓吗?;-)@史蒂夫·杰索普:这很普遍,我希望几乎所有当时写C的人都能很容易地认出它。与其说他是个“流氓”,倒不如说他是个相当进步的人,在以前完全缺乏的代码中添加了
    const
    和原型<代码>\uuu STDC\u VERSION\uuuu在当时是不可靠的。我肯定希望在某个地方“正确”定义参数,这样我就可以在支持它们的编译器上拥有原型,然后在配置时选择要定义的版本。因此,我有点惊讶,文件中没有解释ARGS实际应该如何工作-如果它在所有构建和编译器中都扩展到
    ()
    ,那么您就不必麻烦指定参数列表了。@Steve Jessop:至少在大多数情况下,它是在某个地方或其他地方“正确”定义的,但这个定义取决于(通常是晦涩难懂的)找出正在使用的编译器/版本。由于代码是以这种方式编译的,人们天真地将代码移植到一个新的编译器上,可能很容易去掉编译器的检测结果,就这样离开了。我怀疑作者是个流氓,他是众所周知的:)我的错,没有发布完整的文件和头文件的上下文。我现在就这么做。“像这样的代码很常见”它是如此普遍以至于不值得评论,或者至少是
    \ifndef\uuu STDC\uu VERSION\uuuu
    ?或者我们可以有把握地说作者是个流氓吗?;-)@史蒂夫·杰索普:这很普遍,我希望几乎所有当时写C的人都能很容易地认出它。与其说他是个“流氓”,倒不如说他是个相当进步的人,在以前完全缺乏的代码中添加了
    const
    和原型<代码>\uuu STDC\u VERSION\uuuu在当时是不可靠的。我肯定希望在某个地方“正确”定义参数,这样我就可以在支持它们的编译器上拥有原型,然后在配置时选择要定义的版本。因此,我有点惊讶,文件中没有解释ARGS实际应该如何工作-如果它在所有构建和编译器中都扩展到
    ()
    ,那么您就不必麻烦指定参数列表了。@Steve Jessop:至少在大多数情况下,它是在某个地方或其他地方“正确”定义的,但这个定义取决于(通常是晦涩难懂的)找出正在使用的编译器/版本。由于代码是以这种方式编译的,人们天真地将代码移植到一个新的编译器上,可能很容易去掉编译器的检测结果,就这样离开了。我怀疑作者是个流氓,他很清楚