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

时间:2016-08-30 21:04:03

标签: c

在我的C代码中,我想通过内联函数公开静态变量,这样就避免在标准C中使用'extern'属性,一种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,而不需要函数调用的开销。

1 个答案:

答案 0 :(得分:3)

您的代码是非法的(在ISO C和GNU C中):声明为inline的函数体必须出现在与该函数的任何调用相同的转换单元中。但是在你的代码中它没有出现在app.c中,这就是你得到未定义的引用错误的原因。

此外,正如评论中所述,在ISO C中inline函数不是static,也可能没有提及具有内部链接的数组。 (我不知道GNU C在这个领域的规则是什么。)

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

一种选择是将功能取消标记为inline,并将-O2 -flto开关与gcc一起使用。

另一种选择是使用inline函数,但将函数体放在头文件中。在这种情况下,您还需要使用extern int data_array[];等,因为无法在头文件中定义数组。在执行此选项之前,请read this page。以下是一些与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];