C语言标准是否允许嵌套内联函数?

3

我刚刚了解到内联函数也可以在另一个函数的主体中定义。

我正在使用mpicc编译器,以下代码可以成功编译而且没有警告和错误:

#include <stdio.h>

int main() {
    inline int inlinetest(int x) {
        return x * 4;
    }

    printf("%d\n", inlinetest(8));
    return 0;
}

然而,CLion在文件中显示以下错误:
- 在inlinetest{括号:此处不允许函数定义 - 当我尝试调用inlinetest时:C99中无效的隐式声明函数'inlinetest'
我尝试将CMAKE_C_STANDARDC_STANDARD设置为11,但这没有任何区别。
有没有一种方法可以配置CMake或CLion本身,使其不检测到此“错误”?

5
你为什么写"错误"呢?这确实是一个错误。你的句子"I just learned that inline functions can be defined in another function's body as well."是错的。函数内部不能再定义函数。关键字“inline”意味着该函数会被替换成函数调用,它使得8*4代替了inlinetest(8)。它不允许在函数内部定义一个函数。 - undefined
@mch 但如果这是一个错误:为什么编译器不会抱怨呢?我知道inline的作用,但还是很惊讶为什么这样也能工作... - undefined
4
在标准的 C 语言中,你不能在一个函数内定义另一个函数。你可以在函数内部声明一个函数,但它不是嵌套函数。GCC 有一种语言扩展,允许嵌套函数。请参见此处。但这些函数是非标准的,完全取决于编译器。 - undefined
1
@Adam: “标准C”包括了既有严格符合规范的程序,这些程序不允许嵌套函数定义,也有符合规范的程序,这些程序可以嵌套函数定义。 - undefined
@EricPostpischil:谢谢,我不知道这个! - undefined
3个回答

2

我相信你已经知道,你的m̀picc编译器是一个真正编译器的包装器,在你的情况下显然是gcc

在你的示例中,你将inlinetest定义为main中的嵌套函数

嵌套函数是GNU C语言扩展,标准C不支持它们。

gcc将使用默认选项干净地编译您的程序:

$ cat main.c
#include <stdio.h>

int main() {
    inline int inlinetest(int x) {
        return x * 4;
    }

    printf("%d\n", inlinetest(8));
    return 0;
}
$ gcc main.c
$ ./a.out
32

但是如果您指定让gcc强制执行最古老的C标准,它会抱怨。

$ gcc -std=c89 -pedantic main.c
main.c: In function ‘main’:
main.c:4:5: error: ‘inline’ undeclared (first use in this function)
    4 |     inline int inlinetest(int x) {
      |     ^~~~~~
main.c:4:5: note: each undeclared identifier is reported only once for each function it appears in
main.c:4:11: error: expected ‘;’ before ‘int4 |     inline int inlinetest(int x) {
      |           ^~~~
      |           ;

到最新版本:
$ gcc -std=c18 -pedantic main.c
main.c: In function ‘main’:
main.c:4:5: warning: ISO C forbids nested functions [-Wpedantic]
    4 |     inline int inlinetest(int x) {
      |     ^~~~~~

我不熟悉CLion,但那些标榜实时代码分析的IDE总是存在一些问题,即实时分析器可能会在某些方面与编译器不一致。IDE可能会提供一些方式来查看分析器的规则目录并调整它以消除烦人的诊断。但我不希望你能让CLion识别GNU C嵌套函数:它们是神秘的。
因此,我建议您不要挑起这场争斗。您肯定没有找到一个令人信服的理由让您的代码依赖于支持GNU C嵌套函数,所以就不要费心了。

好的,非常感谢你的回答!我的问题中的示例只是我所指的一个最简单的示例。我发现这个情况是在我教授给我们学生分发的代码中。在那段代码中,他使用了许多嵌套函数,其中大部分引用了所定义函数中的变量。我只是想确保这在C语言中是否是标准做法。非常感谢你详细的回答! - undefined

1

C标准允许嵌套函数定义,即允许C实现支持作为核心语言的扩展来支持此类定义:符合标准的程序可以具有嵌套函数定义,但只能与支持它们的编译器一起使用。

C语言不允许嵌套函数定义作为核心语言的一部分进行定义:严格符合标准的程序不包含嵌套函数定义。

如果使用不支持嵌套函数定义的编译器,不能期望轻松提供一个开关以“忽略”由于嵌套函数定义而导致的错误。支持嵌套函数定义需要在编译器中进行刻意设计和工程处理。


1
C标准不支持嵌套函数定义。一些编译器允许它们作为扩展,特别是gcc。然而请注意,由于您的嵌套函数不引用外部函数中的局部变量,因此可以将其定义移到外部函数的主体之外。
#include <stdio.h>

inline int inlinetest(int x) {
    return x * 4;
}

int main() {
    printf("%d\n", inlinetest(8));
    return 0;
}

请注意,编译器可能会忽略inline,而一些现代编译器会根据实际使用情况内联函数,即使没有inline关键字。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接