默认情况下,在项目文件中是否可以看到用C编写的函数?

默认情况下,在项目文件中是否可以看到用C编写的函数?,c,function,extern,C,Function,Extern,我听说中的函数默认称为“extern”。因此,根据这一点,功能范围应该在整个项目内部,不是吗?我想我没见过这个。我只是想知道,默认情况下,它在项目文件中是否真的可见 文章链接: 上面写着: 首先,让我们考虑在函数中使用EXTIN。结果表明,当函数被声明或定义时,隐式地假设EXTN关键字。 intfoo(intarg1,chararg2) 编译器将其视为:extern int foo(int arg1,char arg2) 由于extern关键字将函数的可见性扩展到整个程序,因此可以在整个程序的任

我听说中的函数默认称为“extern”。因此,根据这一点,功能范围应该在整个项目内部,不是吗?我想我没见过这个。我只是想知道,默认情况下,它在项目文件中是否真的可见

文章链接:

上面写着:

首先,让我们考虑在函数中使用EXTIN。结果表明,当函数被声明或定义时,隐式地假设EXTN关键字。 intfoo(intarg1,chararg2)

编译器将其视为:extern int foo(int arg1,char arg2)


由于extern关键字将函数的可见性扩展到整个程序,因此可以在整个程序的任何文件中的任何位置使用(调用)函数,只要这些文件包含函数的声明。(函数声明到位后,编译器知道函数的定义存在于其他地方,并继续编译文件)。因此,这就是关于外部和函数的所有内容。”

您可以在C11标准草案N1570的“6.2.2标识符链接”部分找到这一点

它说:

如果函数的标识符声明没有存储类说明符,则其链接 与使用存储类说明符extern声明时完全相同


您可以在C11标准草案N1570的“6.2.2标识符链接”章节中找到这一点

它说:

如果函数的标识符声明没有存储类说明符,则其链接 与使用存储类说明符extern声明时完全相同


是的,所有函数(如果没有其他修饰符)都是隐式外部函数。您可以使用静态修饰符对其进行修改,使函数仅对写入的文件可见。另一个非常常见的用法是外部内联函数,它使内联函数对其他文件可见,而不仅仅是它们在其中定义的模块可见。

是所有函数(如果没有其他修改器)是隐式外部的。您可以使用静态修饰符对其进行修改,使函数仅对写入它的文件可见。另一个非常常见的用法是外部内联,它使内联函数对其他文件可见,而不仅仅是它们在其中定义的模块。

对于函数def,使用
外部修饰符是可选的初始化。然而,许多C开发人员使用它作为一种风格,向阅读源代码的人表明在同一文件中查找函数定义没有意义。

对于函数定义,使用
extern
修饰符是可选的。然而,许多C开发人员使用它作为一种风格,表示o阅读源代码的人认为在同一个文件中查找函数的定义毫无意义。

是的,C默认为filescope中新命名对象的全局可见性,除非它们声明为
静态

请注意,
extern
并不表示全局可见性。它表示以前声明的可见性或(如果以前没有这样的声明)全局可见性

extern
对于非静态函数(对于新的(C>=C11)内联函数有一些特殊含义)是可选的,但是对于filescope变量声明,有时需要区分声明和暂定定义

示例:

void globalFunc(void);
void globalFunc(void){ }

static void fileLocalFunc(void);
void fileLocalFunc(void){ } //ok, file-local because the previous declaration was file-local

static void another_fileLocalFunc(void);
extern void another_fileLocalFunc(void){ } //extern is optional for functions

static int fileLocal_variable;
extern int fileLocal_variable; //ok, file-local, because the previous declaration was file-local

//some noncompiling stuff:
#if 0 || CONFLICTING_FUNC_DECLARATIONS0
extern void conflictingFuncDeclarations0(void);
static void conflictingFuncDeclarations0(void);
#endif
#if 0 || CONFLICTING_FUNC_DECLARATIONS1
void conflictingFuncDeclarations1(void);
static void conflictingFuncDeclarations1(void);
#endif

#if 0 || CONFLICTING_VAR_DECLARATIONS0
int conflictingVarDeclarations0;
static int conflictingVarDeclarations0;
#endif

如果您在POSIX系统上,您可以将翻译单元编译成一个对象(
*.o
)文件,然后使用该文件上的
nm
实用程序查看它导出(或尝试导入)的名称。

是的,C默认为文件范围中新命名对象的全局可见性,除非它们声明为
static

请注意,
extern
并不表示全局可见性。它表示以前声明的可见性或(如果以前没有这样的声明)全局可见性

extern
对于非静态函数(对于新的(C>=C11)内联函数有一些特殊含义)是可选的,但是对于filescope变量声明,有时需要区分声明和暂定定义

示例:

void globalFunc(void);
void globalFunc(void){ }

static void fileLocalFunc(void);
void fileLocalFunc(void){ } //ok, file-local because the previous declaration was file-local

static void another_fileLocalFunc(void);
extern void another_fileLocalFunc(void){ } //extern is optional for functions

static int fileLocal_variable;
extern int fileLocal_variable; //ok, file-local, because the previous declaration was file-local

//some noncompiling stuff:
#if 0 || CONFLICTING_FUNC_DECLARATIONS0
extern void conflictingFuncDeclarations0(void);
static void conflictingFuncDeclarations0(void);
#endif
#if 0 || CONFLICTING_FUNC_DECLARATIONS1
void conflictingFuncDeclarations1(void);
static void conflictingFuncDeclarations1(void);
#endif

#if 0 || CONFLICTING_VAR_DECLARATIONS0
int conflictingVarDeclarations0;
static int conflictingVarDeclarations0;
#endif

如果您在POSIX系统上,您可以将翻译单元编译成一个对象(
*.o
)文件,然后使用该文件上的
nm
实用程序查看它导出(或尝试导入)的名称。

谢谢。您介意解释一下吗,“不仅仅是它们在其中定义的模块。”和“外部内联”?当然,内联是一个函数说明符,它“提示”编译器它可以像处理宏一样处理函数(但它可能会忽略它)。它对于其他文件不可见(因为标准中的“内联”定义),除非指定了extern。(我找到了这个源代码,它解释得很好:)。谢谢。您介意解释一下吗,“不仅仅是它们在其中定义的模块。”和“外部内联”?当然,内联是一个函数说明符,它“提示”编译器它可以像处理宏一样处理函数(但它可能会忽略它)。除非指定了外部,否则它对其他文件不可见(因为标准中的“内联”定义)。(我找到了这个来源,它解释得很好:)。在这篇文章中有一个关于
extern
含义的有趣讨论:在这篇文章中有一个关于
extern
含义的有趣讨论: