C 通过内联函数公开静态变量

C 通过内联函数公开静态变量,c,C,在我的C代码中,我希望通过内联函数公开静态变量,这样可以避免使用“extern”属性,这在标准C中是一种OOP。但是我无法编译它。考虑下面的代码: $ cat object.h inline int get_value(int index); $ cat object.c #include "object.h" static int data_array[32]; inline int get_value(int index) { return data_array[index]; }

在我的C代码中,我希望通过内联函数公开静态变量,这样可以避免使用“extern”属性,这在标准C中是一种OOP。但是我无法编译它。考虑下面的代码:

$ cat object.h
inline int get_value(int index);
$ cat object.c
#include "object.h"
static int data_array[32];

inline int get_value(int index) {
    return data_array[index];
}
$ cat app.c 
#include "object.h"
void main(void) {
    int datum;

    datum=get_value(8);
}
$ gcc -c object.c
object.c:5:9: warning: ‘data_array’ is static but used in inline function ‘get_value’ which is not static
  return data_array[index];
         ^
$ ls -l object.o
-rw-rw-r-- 1 niko niko 976 Aug 30 15:56 object.o
$ gcc -c app.c
In file included from app.c:1:0:
object.h:1:12: warning: inline function ‘get_value’ declared but never defined
 inline int get_value(int index);
            ^
$ ls -l app.o
-rw-rw-r-- 1 niko niko 1368 Aug 30 15:56 app.o
$ gcc -o app app.o object.o
app.o: In function `main':
app.c:(.text+0xe): undefined reference to `get_value'
collect2: error: ld returned 1 exit status
是否有可能以某种方式访问通过内联函数声明的文件之外的静态变量,该函数将内联到所使用的每个.c文件中?当然我可以声明变量'extern':

extern int data_array[];
并直接引用它,但我想通过一个函数来模拟C中的OOP,而不需要函数调用的开销。

您的代码是非法的(在ISO C和GNU C中):声明为
内联的函数体必须与对该函数的任何调用出现在同一个翻译单元中。但是在您的代码中,它不会出现在
app.c
中,这就是为什么会出现未定义的引用错误

此外,如注释中所述,在ISO C中,非静态的
内联
函数可能未提及具有内部链接的数组。(我不知道GNUC在这方面的规则是什么)

在评论中,你会谈论诸如“呼叫开销”等内容,但这与
内联
关键字几乎没有关系。如果使用优化开关,优化器将生成尽可能快的代码。
inline
关键字的目的是允许函数体出现在头文件中

一个选项是将函数取消标记为
内联
,并将
-O2-flto
开关与gcc一起使用

另一个选项是使用
inline
函数,但将函数体放在头文件中。在这种情况下,您还需要使用
extern int data_array[]etc,因为无法在头文件中定义数组。在做这个选择之前。以下是一些与ISO C和GNU C兼容的代码:

// header file
extern int data_array[];

static inline int get_value(int index)
{
    return data_array[index];
}

// source file
#include "header.h"

int data_array[32];

C11标准草案n1570:6.7.4函数说明符3具有外部链接的函数的内联定义不得包含具有静态或线程存储持续时间的可修改对象的定义,也不得包含对具有内部链接的标识符的引用。@EOF太糟糕了。。。我想知道人们是如何通过内联函数在C中模拟OOP的?唯一可行的选择是宏,我想…这不是
内联
的意思…在一个文件中,做
int-data\u-array[32]
,在(例如,
data.h
文件中做:
extern-int-data\u-array[]
并将内联
get_array
函数也放在那里。另外,添加一条注释,告诉人们只能通过
get\u array
访问阵列。如果他们违反了这一点,他们的代码就会被破坏。我不相信“信息隐藏”。许多风格的指南认为这是不好的实践。你想做的是,嗯,只是有点“太可爱了”。C不是一个超级监狱。这是一种编程语言,我们使用“荣誉系统”,你必须选择你的战斗。我使用了带有静态变量的库。作者假设库的[合法]用户不需要访问。但是,这就是选择通常只是一个(一厢情愿的)猜测。如果lib用户的使用需要访问,因为他们合法地做了lib作者没有预料到的事情,那么lib用户就处于困境。我很少使用静电。因此,为了避免与通用名称冲突,我使用了
int-mylib\u-value
,而不是
static int-value
,所有全局变量都是mylib\u*它也有助于
vi`grep-lr-mylib\u-value.`
@AnT这是一个C答案(正如我在答案中多次说“C”而不是“C++”)。参见C11 6.7.4/7“对于具有外部链接的函数,以下限制适用:如果函数是使用
内联
函数说明符声明的,则它也应在同一翻译单元中定义。”(6.2.3/5涵盖
内联int get_值(int);
声明具有外部链接的函数)。我现在在答复中改变了那一段的措辞;函数体在调用之后但在同一个单元内是合法的。是的,你是对的。我在考虑另一件事。@AnT好的,如果你愿意,我们可以删除评论like@M.M在GCC文档中,我发现一条语句,使用内联函数消除函数调用开销。直接引用:“这通过消除函数调用开销使执行更快”参考:当进行函数调用时,它生成4条汇编指令:调用、推送、弹出和RET@Nulik尝试查看生成的程序集(启用优化)