2016-08-30 2 views
0

In meinem C-Code möchte ich statische Variablen durch Inline-Funktionen offenlegen, und auf diese Weise vermeiden Sie 'extern' Attribut, Art von OOP in Standard C. Allerdings kann ich es nicht kompilieren. Betrachten Sie den folgenden Code ein:statische Variable durch eine Inline-Funktion freilegen

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

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

    datum=get_value(8); 
} 
[[email protected] snippets]$ 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]; 
     ^
[[email protected] snippets]$ ls -l object.o 
-rw-rw-r-- 1 niko niko 976 Aug 30 15:56 object.o 
[[email protected] snippets]$ 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); 
      ^
[[email protected] snippets]$ ls -l app.o 
-rw-rw-r-- 1 niko niko 1368 Aug 30 15:56 app.o 
[[email protected] snippets]$ 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 
[[email protected] snippets]$ 

Ist es möglich, statische Variablen zugreifen irgendwie wurden sie durch eine Inline-Funktion außerhalb der Datei erklärt, dass in jedem C-Datei inlined würde es verwendet wird? Natürlich kann ich erklären, nur die Variable ‚extern‘:

extern int data_array[]; 

und direkt verweisen, aber ich mag sie durch eine Funktion tun OOP in C von einem Funktionsaufruf ohne den Aufwand zu simulieren.

+4

C11 Norm-Entwurf n1570: * 6.7.4 Funktion Bezeich 3 Eine Inline-Definition einer Funktion mit externer Bindung ist keine Definition eines modifizierbar enthalten Objekt mit statischer oder Thread-Speicherdauer, und darf keinen Verweis auf einen Bezeichner mit interner Verknüpfung enthalten. * – EOF

+0

@EOF zu schlecht ... Ich frage mich, wie Menschen OOP in C durch Inline-Funktionen simulieren? die einzige brauchbare Alternative wären Makros, denke ich ... – Nulik

+0

Ich sehe nicht, wie ein Makro in irgendeiner Weise helfen würde. Ich bin mir nicht sicher, warum Sie darauf bestehen, dass die Funktionen inline sind. – EOF

Antwort

2

Ihr Code ist illegal (sowohl in ISO C als auch in GNU C): Der Rumpf einer Funktion, die als inline deklariert ist, muss in der gleichen Übersetzungseinheit wie jeder Aufruf dieser Funktion erscheinen. Aber in Ihrem Code erscheint es nicht in app.c, weshalb Sie den undefinierten Referenzfehler erhalten.

Weiter, wie in den Kommentaren erwähnt, in ISO C eine inline Funktion, die nicht auch static ist, darf ein Array mit interner Verknüpfung nicht erwähnen. (Ich weiß nicht, was die Regeln von GNU C in diesem Bereich sind).

In Kommentaren sprechen Sie über Sachen wie "Overhead von CALL" usw. Aber das hat wenig oder nichts mit dem Stichwort inline zu tun. Der Optimierer erzeugt den schnellstmöglichen Code, wenn Sie einen Optimierungsschalter verwenden. Der Zweck des Schlüsselworts inline besteht darin, Funktionskörper in Headerdateien anzuzeigen.

Eine Option wäre, die Funktion als inline zu entfernen und die -O2 -flto Schalter mit gcc zu verwenden.

Eine weitere Option ist die Verwendung der inline-Funktion, aber den Funktionskörper in die Header-Datei. In diesem Fall müssen Sie auch extern int data_array[]; usw. verwenden, da es nicht möglich ist, das Array in der Header-Datei zu definieren. Bevor Sie diese Option ausführen, geben Sie read this page ein. Hier ist ein Code, der sowohl mit ISO C und GNU C kompatibel ist:

// 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]; 
+0

@AnT this ist eine C-Antwort (wie mir gezeigt wurde, indem ich "C" mehrmals in der Antwort sage und nicht "C++"). Siehe C11 6.7.4/7 "Für eine Funktion mit externer Verknüpfung gelten folgende Einschränkungen: Wenn eine Funktion mit einem 'inline'-Funktionsspezifizierer deklariert ist, dann muss sie auch in derselben Übersetzungseinheit definiert sein." (6.2.3/5 deckt das ab: 'inline int get_value (int); 'deklariert eine Funktion mit externer Verknüpfung). Ich habe den Wortlaut dieses Absatzes jetzt in meiner Antwort geändert; Es ist zulässig, dass sich der Funktionskörper nach dem Anruf befindet, jedoch innerhalb derselben Einheit. –

+0

Ja, Sie haben Recht. Ich habe über eine andere Sache nachgedacht. – AnT

+0

@AnT OK, wir können Kommentare entfernen, wenn Sie möchten –

Verwandte Themen