Ich möchte ein konstantes Array deklarieren, auf das von mehreren C-Dateien zugegriffen werden kann und dessen Inhalt vom Compiler inline geschrieben werden kann, ohne den Speicher in mehreren Kompilierungseinheiten zu duplizieren. Leistung ist in meiner Anwendung von entscheidender Bedeutung.Inlinable konstantes C-Array ohne Speicherverdoppelung
Exhibit 1:
header.h:
static const int arr[2] = { 1, 2 };
file1.c:
#include "header.h"
void file1() { printf("%d\n", arr[0]); }
file2.c:
#include "header.h"
int file2() { for (int i = 0; i < 2; i++) printf("%d\n", arr[i]); }
In diesem Fall kann der Compiler arr[0]
durch 1
in file1 ersetzen. Da jedoch arr
als static const
deklariert ist, ist sein Speicher in beiden C-Dateien dupliziert. AFAIK der C-Standard erfordert, dass die Array-Adressen in beiden Dateien unterschiedlich sind. Ich habe dies unter Linux durch Ausdrucken der Adressen verifiziert. Selbst mit -fmerge-all-constants
in gcc tritt keine Linker-Konsolidierung auf.
Exhibit 2:
header.h:
extern const int arr[2];
file1.c:
#include "header.h"
void file1() { printf("%d\n", arr[0]); }
file2.c:
#include "header.h"
const int arr[2] = { 1, 2 };
int file2() { for (int i = 0; i < 2; i++) printf("%d\n", arr[i]); }
In diesem Fall tritt kein Memory-Duplizierung aber arr[0]
nicht inlined ist.
Ich betrachte den durch den C-Standard definierten Sichtbarkeitsbereich als fehlerhaft. Daher ist eine funktionierende Lösung unter Linux/gcc akzeptabel, die gegen den C-Standard verstößt.
Eigentlich 'file2' ermöglicht auch die Anordnung inlining. 'gcc -O9 'entrollt die Schleife und drückt direkt die beiden Werte. – aschepler
@ascheppler: Ja. Auf meinem System stoppt der Compiler mit -O2, sobald ich drei oder mehr Elemente im Array gesetzt habe. –