C中块内的函数声明

Function declaration inside of block in C

C 标准 (C99+) 是否要求实现允许将函数声明放置在一个块中,以便将它们的范围限制在该块中标准中涵盖了哪些内容?假设该函数具有外部链接并且在链接时包含在单独的源文件中定义。

我注意到 GCC 在编译以下程序时会产生错误:

int main(void)
{
  void myFunc(void);

  myFunc();

  return 0;
}

void test2(void)
{
  myFunc();
}

错误(预期):

..\main.c: In function 'test2':
..\main.c:12:3: warning: implicit declaration of function 'myFunc' [-Wimplicit-function-declaration]
   12 |   myFunc();
      |   ^~~~~~
..\main.c:3:8: note: previous declaration of 'myFunc' was here
    3 |   void myFunc(void);
      |        ^~~~~~
..\main.c:12:3: error: incompatible implicit declaration of function 'myFunc'
   12 |   myFunc();
      |   ^~~~~~
..\main.c:3:8: note: previous implicit declaration of 'myFunc' was here
    3 |   void myFunc(void);
      |        ^~~~~~

这是意料之中的,因为 myFunc() 是在 main() 的范围内声明的。

如果从 test2() 中删除对 myFunc() 的调用,并且 test2() 在链接时包含的另一个源文件中定义,则程序编译和链接时不会出现错误或警告.

根据这个结果,问题的答案是肯定的,但我想知道这种行为是否在规范中明确定义并且可以被认为是可移植的。

Does the C standard (C99 +) require the implementation to allow function declarations to be placed within a block in order to limit their scope to that block?

是的。

where is this covered in the standard?

遵循语法:function-definition -> compund-statement -> block-item-list -> block-item -> declaration-specifiers -> [declaration-specifiers -> type-specifier void + init-declarator-list -> init-declarator -> 声明符 -> [ direct-declarator myFunc + ( + 空 identifier-list + ) ]+ ; ].

用于表示文法的符号也有解释:https://port70.net/~nsz/c/c99/n1256.html#6.1p1 .

换句话说,一个函数定义有一段block的代码,由声明和表达式组成。函数声明是可能的声明之一,因此它可以在函数定义内的块内。

函数内

void test2(void)
{
  myFunc();
}

名称 myFunc 未声明。

函数的声明仅在 main 中可见。

为了向后兼容,编译器认为该函数具有 return 类型 int

至于你的问题,那么你可以在块范围内声明一个函数,但没有存储 class 说明符,除了 extern (C 标准,6.7.1 Storage-class 说明符) :

6 The declaration of an identifier for a function that has block scope shall have no explicit storage-class specifier other than extern.

也就是说你不能在块范围内声明一个函数,例如

int main(void)
{
  static void myFunc(void);

  myFunc();

  return 0;
}