标准C和现代编译器之间的差异

时间:2016-03-01 19:36:12

标签: c

int h, i; 
void B(int w) {
    int j, k;
    i = 2 * w;
    w = w + 1;
    ...
}
void A(int x, int y) { 
    float i, j;
    B(h); 
    i = 3;
    ... 
}
int main() {
    int a, b;
    h = 5; a = 3; b = 2;
    A(a, b);
    B(h);
    return 0;
}

就现代编译器而言,我发现函数A()不允许调用函数B()。我发现像gcc和turboc这样的编译器也一样。

  

我从我的教授那里听说标准C允许B()使用相同的代码调用A(),反之亦然。这是真的吗?

在哪里可以找到有关标准C的实际概念的更多信息?

2 个答案:

答案 0 :(得分:4)

(发表此答案,因为主要评论中存在许多误解):

  • 在所有版本的标准C中,A可以致电BB可以致电A
  • 任何版本的标准C都不需要原型。(但最好还是使用原型,因为它们可以帮助编译器诊断错误。)
  • 在ISO C99和ISO C11中,函数声明必须对要调用的函数可见。
  • 在ISO C90中,可以在没有可见声明的情况下调用函数。如果满足以下所有条件,则此调用将正确运行(否则行为未定义):
    • 函数定义返回int(或省略返回类型)
    • 函数定义不是variadic
    • 在应用默认参数提升之后,参数类型的有序列表与参数类型的有序列表完全匹配到函数定义(不提升参数类型)。

例如,在标准C的所有版本中,...内的OP代码中的B()可能会替换为:

void A();
A(w, i);

制作正确的节目。在ISO C90中,...可以简单地替换为:

A(w, i);

标准使得这一法律合法化,以避免破坏在原型发明之前编写的现有代码。如果K& R1中的代码停止在标准C中工作,那将是令人尴尬的。

我重申,如果您正在编写新代码,那么故意这样做并不是一个好主意;最好放一个原型,原型的最佳位置不在功能范围内。

您可以下载ISO C11标准和ISO C99 + TC3标准here的草稿。 AFAIK没有C90或原始C99文本的免费和合法副本。获得C90文本的最便宜的合法方式是购买书籍The Annotated C Standard。这比从ISO购买它便宜,尽管据说价格差异代表了注释的附加价值。

有很多关于标准C的二手资料来源,例如:本网站上标有的问题。

答案 1 :(得分:-1)

  

标准C允许B()调用A(),反之亦然

当然这是真的,这就是源文件顶部的函数原型的全部概念;或者在单独的头文件中更好。

void B(int w);  // <-- as long as these prototypes are available, the actual function implementation can be any where.
void A (int x,int y);