Hallo allesamt
Ich habe folgendes Problem:
Ich habe ein Struct für Sensoren definiert welches einen Sensortyp in
Form eines Enums hat und außerdem eine Union, in der 2 Sensorentypen
enthalten sind
1
typedefunion{
2
3
Lightl;
4
Temperaturet;
5
6
}sensor_details;
7
8
typedefstruct{
9
10
sensortypestype;
11
sensor_detailsdetails;
12
13
}sensor_types;
Nun will ich in meiner Main-Funktion diese initialisieren bekomme aber
folgendes Warning für die Zeile wo type2 initialisiert werden soll:
Dieser Fehler tritt aber nur auf wenn ich eine Initialisierung des
zweiten Sensortyps in sensor_details vornehmen möchte, sprich tausche
ich die Reihenfolge von Light und Temperature funtkioniert die type1
Initialisierung nicht.
Definiere ich type1 oder type2 als static bekomme ich die Fehlermeldung:
1
error:initializerelementisnotconstant
2
error:(nearinitializationfor‘type1.details.l’)
Diese Meldung weißt auf ein Problem hin was ich schon mehrfach gelesen
habe, nämlich dass die Initialisierung einer global definierten Union
zur Compilezeit mit der Zuweisung eines Funktionsaufrufes nicht erlaubt
ist.
Liege ich komplett auf dem Holzweg, gibt es eine Lösung für das Problem?
Ich befürchte ich denke mal wieder zu kompliziert!
Manchmal kommt die Erkenntnis erst wenn man drüber redet/schreibt :-D
Also ich muss wohl noch explizit in der Initialisierung angeben welchem
Typ in der Union der Funktionsaufruf zugewiesen werden soll, ansonsten
nimmt der Kompiler immer den ersten Typ an:
Es funktioniert, indem ich diese Zeile:
Macht im Nachhinein auch Sinn, dennoch hätte ich die Zuweisung schon
gerne in einem Schritt gemacht. Ist das möglich oder funktioniert es nur
in mehreren Schritten?
So was in der Art :
Wenn Du C++ programmierst, dann könntest Du auch die Möglichkeiten
nutzen, die C++ bietet. Für Deine unterschiedlichen Initialisierungen
böten sich unterschiedliche Konstruktoren an; Deine Struktur ist in C++
sowieso äquivalent zu einer Klasse.
(der Unterschied zwischen struct und class besteht nur in der
Default-Anwendung von protected/private/public)
Daniel T. schrieb:> warning: initialization from incompatible pointer type
Diese Warnung meint in der Regel genau das, was sie sagt. Da passt ein
Initialisierungstyp (Pointer) nicht zum Variablentyp. Da du aber nicht
alle Deklarationen hier zeigst (ich sehe da gar keine pointer), musst du
das schon selber ergründen.
Allerdings gibt es in der Zeile davor vermutlich (Funktions-)pointer.
Bist du sicher, daß sich die Warnung nicht auf die Zeile
>Sensor sensor1 = ...
bezieht?
Oliver
@rufus
Ja mittlerweile hab ich so viele Elemente aus der Objektorientierung
drin, dass es mehr Sinn macht C++ zu nutzen. Aber in anbetracht der mir
verbleibenden Zeit für dieses Projekt bleibe ich vorerst bei der
Variante. Vielleicht wird die Version 2 dann umgeschrieben ;-).
Dazu hab ich dann aber gleich eine allgemeine Frage, macht es denn Sinn
auf einem MCU in C++ zu programmieren? Klar bei den Anforderungen die
ich im Moment habe wie z.B. Sensorobjekte schon aber betrachtet man dann
den kompletten Code, ist dieser dann doch wesentlich speicher- und
leistungsintensiver ?
@Oliver
Ok hab nun nicht den kompletten Code hier reinposten wollen , also in
der selben Datei sind die beiden Sensortypen Light und Temperatur durch
Structs und Typedefs definiert, dort findest du dann auch die Pointer
auf die Structs:
1
typedefstructtemp_sensor*Temperature;
2
typedefstructlight_sensor*Light;
3
4
structtemp_sensor{
5
6
outputunitunit;
7
floatmin_value;
8
floatmax_value;
9
};
10
11
structlight_sensor{
12
13
outputunitunit;
14
floatmin_value;
15
floatmax_value;
16
floatred_part;
17
floatgreen_part;
18
floatblue_part;
19
};
Aber wie schon gesagt warum der Fehler nun entstanden ist habe ich ja
mittlerweile rausgefunden, im erst genannten Beispiel hat der Compiler
versucht einem Light Struct ein Temperature Struct zuzuweisen, da ich
nicht explizit die Zuweisung des richtigen Feldes aus der Union
vorgenommen habe.
>> Macht im Nachhinein auch Sinn, dennoch hätte ich die Zuweisung schon> gerne in einem Schritt gemacht. Ist das möglich oder funktioniert es nur> in mehreren Schritten?
Das Kompilat könnte in beiden Fällen gleich aussehen - muss es aber
nicht. Beim Aggregat wird zuweilen eine vollständige
Initialisierungskopie gehalten (memcpy), bei 'static' wäre diese Methode
natürlich ohne Runtime-Overhead.
Ich hatte bei einem GNU-C-Compiler (21020er DSP) immer das Problem, dass
Aggregatzuweisungen sogar ein Vielfaches des Codes erzeugt hatten. Die
direkten Einzelzuweisungen lieferten bei Stack-Variablen grundsätzlich
den kompakteren und damit besseren Code.
Die Aggregatzuweisung ist außerdem zwar vielleicht kompakt im Quellcode,
auf der anderen Seite sieht man aber auch nicht mehr, was man da tut.
> Macht im Nachhinein auch Sinn, dennoch hätte ich die Zuweisung schon> gerne in einem Schritt gemacht. Ist das möglich oder funktioniert es nur> in mehreren Schritten?