Ich erhalte eine Fehlermeldung in Zeile 6 (initialisiere my_foo auf foo_init) des folgenden Programms und bin mir nicht sicher, warum.
typedef struct foo_t {
int a, b, c;
} foo_t;
const foo_t foo_init = { 1, 2, 3 };
foo_t my_foo = foo_init;
int main()
{
return 0;
}
Beachten Sie, dass dies eine vereinfachte Version eines größeren Projekts mit mehreren Dateien ist, an dem ich arbeite. Das Ziel war es, eine einzige Konstante in der Objektdatei zu haben, mit der mehrere Dateien eine Statusstruktur initialisieren können. Da es sich um ein eingebettetes Ziel mit begrenzten Ressourcen handelt und die Struktur nicht so klein ist, möchte ich nicht mehrere Kopien der Quelle. Ich würde es vorziehen, nicht zu verwenden:
#define foo_init { 1, 2, 3 }
Ich versuche auch, portablen Code zu schreiben, daher benötige ich eine Lösung, die C89 oder C99 gültig ist.
Hat dies mit den ORGs in einer Objektdatei zu tun? Dass initialisierte Variablen in eine ORG gehen und durch Kopieren des Inhalts einer zweiten ORG initialisiert werden?
Vielleicht muss ich nur meine Taktik ändern und alle Kopien beim Start von einer Initialisierungsfunktion ausführen lassen. Es sei denn, es gibt andere Ideen da draußen?
quelle
enum { N = 5 };
ist eine unterschätzte Methode, Konstanten zu deklarieren, ohne darauf zurückgreifen zu müssen#define
.static int* ptr = malloc(sizeof(int)*5);
aber dies ist KEIN Fehlerstatic int* ptr; ptr = malloc(sizeof(int)*5);
Es ist eine Einschränkung der Sprache. In Abschnitt 6.7.8 / 4:
In Abschnitt 6.6 definiert die Spezifikation, was als konstanter Ausdruck betrachtet werden muss. Nein, wo steht, dass eine const-Variable als konstanter Ausdruck betrachtet werden muss. Es ist für einen Compiler legal, this (
6.6/10 - An implementation may accept other forms of constant expressions
) zu erweitern, dies würde jedoch die Portabilität einschränken.Wenn Sie Änderungen vornehmen können,
my_foo
damit kein statischer Speicher vorhanden ist, sind Sie in Ordnung:quelle
static const int x = 3; static int y = x;
.Nur zur Veranschaulichung durch Vergleich und Kontrast Der Code stammt von http://www.geeksforgeeks.org/g-fact-80/ / Der Code schlägt in gcc fehl und wird in g ++ / übergeben
quelle
Das ist ein bisschen alt, aber ich bin auf ein ähnliches Problem gestoßen. Sie können dies tun, wenn Sie einen Zeiger verwenden:
quelle
gcc 7.4.0 kann keine Codes wie folgt kompilieren:
constchar.c: 3: 21: Fehler: Initialisiererelement ist nicht konstant const char * str2 = str1;
Tatsächlich ist eine Zeichenfolge "const char *" keine Konstante zur Kompilierungszeit, daher kann sie kein Initialisierer sein. Ein "const char * const" -String ist jedoch eine Konstante zur Kompilierungszeit. Er sollte ein Initialisierer sein können. Ich denke, das ist ein kleiner Nachteil von CLang.
Ein Funktionsname ist natürlich eine Konstante zur Kompilierungszeit. Dieser Code funktioniert also:
quelle
str1
ist kein Ausdruck gemäß 6.7.9 Initialisierung , Absatz 4 : "Alle Ausdrücke in einem Initialisierer für ein Objekt mit statischer oder Thread-Speicherdauer müssen konstante Ausdrücke oder Zeichenfolgenliterale sein."