mikrocontroller.net

Forum: Compiler & IDEs wie übergibt man einen uint16_t* als uint32_t*


Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ich versteh das echt nicht. Ich hab hier diesen Code mit folgender 
Funktion:
int main(void) 
{
    uint16_t bonus = 0;
    Add(&bonus,1,5999);
}

void Add(uint32_t* source, int32_t add, uint32_t max)
{
    int32_t tmp = *source + add;
    if(tmp >= 0 && tmp <= max)
        *source = tmp;
}

bonus hat danach immernoch 0. Das Wenn man jetzt bonus statt uint16 als 
uint32 deklariert funktioniert es. Kann mir jemand sagen, wie ich das 
mache? Einfach uint16_t in der Funktion benutzen geht nicht, da das nur 
ein Beispiel ist, und ich verschiedene Variablen in meinem Programm hab.

Irgendwie muss man das doch übergeben können, dass es auch funktioniert.

Autor: sebastians (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Irgendwie muss man das doch übergeben können, dass es auch funktioniert.
Nein, kann man nicht. Wenn da ein uin32_t* verlangt wird, muss du auch 
einen Zeiger auf eine Variable reingeben, die gross genug ist.

Aber du kannst sowas machen:
int main(void) 
{
    uint16_t bonus = 0;
    ...
    {
        uin32_t hilfsvariable = bonus;
        Add(&hilfsvariable,1,5999);
        if(hilfsvariable <= 0xFFFF)
        {
            bonus = hilfsvariable;
        }
        else
            ...
    }
}

Vielleicht macht es auch Sinn, das Ergebnis so zurückzuliefern:
uint32_t Add(uint32_t source, int32_t add, uint32_t max);

int main(void) 
{
    uint16_t bonus = 0;
    bonus = Add(bonus,1,5999);
}

uint32_t Add(uint32_t source, int32_t add, uint32_t max)
{
    int32_t tmp = source + add;
    if(tmp >= 0 && tmp <= max)
        return tmp;
    else
        return source;
}


PS:
tmp >= 0
 ist immer TRUE.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da hätte der GCC dir aber normalerweise eine Warnung ausgeben müssen, 
daß der Typ nicht passt. Warnungen ausgeschaltet oder nur einfach 
ignoriert?

Samuel K. schrieb:
> Kann mir jemand sagen, wie ich das mache? Einfach uint16_t in der Funktion
> benutzen geht nicht, da das nur ein Beispiel ist, und ich verschiedene
> Variablen in meinem Programm hab.

Wenn du über einen Zeiger auf uint32_t einen Zugriff machst, liest und 
schreibt der Compiler das, worauf er zeigt, natürlich auch als uint32_t.
Wo soll er denn auch den 32-Bit-Wert hernehmen, auf den du mit dem 
Zeiger zugreifen willst?

> Irgendwie muss man das doch übergeben können, dass es auch funktioniert.
    uint32_t tmp = bonus;
    Add(&tmp,1,5999);
    bonus = tmp;

Alternativ übergib es einfach per Wert und gib aus der Funktion das 
Ergebnis per return zurück.

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja die Warnung gabs. Naja ich werde mir jetzt ne Add32, Add16 und Add8 
funktion anlegen (Warum kann man in c auch keine Funktionen 
überladen!!!).

sebastians schrieb:
> PS:tmp >= 0 ist immer TRUE.

Das add Argument ist int32, und ich dachte wenn eine unsigned und eine 
signed zahl addiert werden, muss doch ein signed ergebnis rauskommen, 
oder weß ich das falsch.

Bsp:

uint8_t a = 5;
int8_t b = -7;
int8_c = a + b;

dann ist c doch -2, oder muss ich doch noch (int8_t) davor schreiben?

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es kommt trotzdem die Warnung

18 [Warning] passing argument 1 of 'Add32' discards qualifiers from 
pointer target type

Was heißt das?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:
> Ja die Warnung gabs. Naja ich werde mir jetzt ne Add32, Add16 und Add8
> funktion anlegen (Warum kann man in c auch keine Funktionen
> überladen!!!).

Dann wären wir beim ersten Schritt in Richtung C++ :-)

> sebastians schrieb:
>> PS:tmp >= 0 ist immer TRUE.
>
> Das add Argument ist int32, und ich dachte wenn eine unsigned und eine
> signed zahl addiert werden, muss doch ein signed ergebnis rauskommen,
> oder weß ich das falsch.

Das siehst du falsch

> Bsp:
>
> uint8_t a = 5;
> int8_t b = -7;
> int8_ c = a + b;
>
> dann ist c doch -2, oder muss ich doch noch (int8_t) davor schreiben?

aber nur weil c eine int8_t Variable ist.
Das Ergebnis von a + b ist unsigned

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:
> Es kommt trotzdem die Warnung
>
> 18 [Warning] passing argument 1 of 'Add32' discards qualifiers from
> pointer target type
>
> Was heißt das?

Das du den echten Code, so wie er jetzt ist, herzeigen solltest.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
[quote]
If both operands have the same type, then no further conversion is 
needed.

Otherwise, if both operands have signed integer types or both have 
unsigned integer types, the operand with the type of lesser integer 
conversion rank is converted to the type of the operand with greater 
rank.

Otherwise, if the operand that has unsigned integer type has rank 
greater or equal to the rank of the type of the other operand, then the 
operand with signed integer type is converted to the type of the operand 
with unsigned integer type.

Otherwise, if the type of the operand with signed integer type can 
represent all of the values of the type of the operand with unsigned 
integer type, then the operand with unsigned integer type is converted 
to the type of the operand with signed integer type.

Otherwise, both operands are converted to the unsigned integer type 
corresponding to the type of the operand with signed integer type.
[/quote]

C-Standard, 6.3.1.8/1

In Kurzfassung:
Wenn es zu der Konstallation signed/unsigned kommt, gewinnt signed nur 
dann, wenn der signed Datentyp alle Werte des unsigned Datentyps 
aufnehmen kann. In allen anderen Fällen gewinnt unsigned.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:

> Was heißt das?

Dass du nicht weißt, was ein type qualifier ist und trotzdem welche
benutzt hast. ;-)

"type qualifiers" sind die Schlüsselworte "const", "volatile" und
(C99) "restricted".  Einen von denen hat offenbar das Objekt, das
du übergibst, während die Funktion einen Zeiger auf einen nicht
derart bestimmten Typ erwartet.

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entschuldigt, ich bin noch recht neu auf der µC programmierung. Am PC 
konnte ich immer int nehmen und hatte sowohl im negativen als auch 
positiven Bereich genügend Werte.

Aber, danke ich hab das jetzt alles gecastet und jetzt funktioniert das 
ganze.

Karl heinz Buchegger schrieb:
> Das du den echten Code, so wie er jetzt ist, herzeigen solltest.
--> Codesammlung, das war der größte Bug in der Schachuhr (ich hab jetzt 
eine die verbesserte Verion hochgeladen).

Und von c++ auf c umzusteigen ist ein richtiger Schlag, allein 
überladene Funktionen brauchte ich oft. OOP vermisse ich auch.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:
> Aber, danke ich hab das jetzt alles gecastet und jetzt funktioniert das
> ganze.

Weißt du auch, warum? Casten sollte man nur, wenn man genau weiß, warum 
man den Cast braucht.

Samuel K. schrieb:
> Und von c++ auf c umzusteigen ist ein richtiger Schlag, allein
> überladene Funktionen brauchte ich oft. OOP vermisse ich auch.

Du hast bisher nichts über die Zielplattform geschrieben, aber auf den 
meisten, wo es gcc gibt, gibt's auch g++.

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, wenn ich eine Schachuhr baue, wird das wohl ein µC (Atmega8 ist 
es) sein. Und den kann man meines Wissens nicht in c++ programmieren.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:
> Und den kann man meines Wissens nicht in c++ programmieren.

Du solltest deinen Wissensstand aktualisieren...  Du kannst davon
ausgehen, dass Rolf schon bewusst war, dass du einen Controller
programmieren willst. ;-)

ATmega8 würde ich mir für eine Neuentwicklung überdenken, zugunsten
eines ATmega88.  Hat ein wenig Hardware mehr, lässt sich online
debuggen (bspw. mit einem AVR Dragon) und besitzt noch kleinere
und vor allem größere Geschwister, falls es mit dem Platz aus
irgendeinem Grund (und sei's nur zum Debuggen) knapp wird.  Diese
sind pin- und sourcecodekompatibel.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Samuel K. schrieb:
> Naja, wenn ich eine Schachuhr baue, wird das wohl ein µC (Atmega8 ist
> es) sein.

Ja, bekanntlich gibt's ja außer AVR sonst keine µCs. ;-)

> Und den kann man meines Wissens nicht in c++ programmieren.

Doch, kann man. Du wirst zwar auf die Standardbibliothek und Dinge wie 
Exceptions verzichten müssen, aber z.B. Funktionsüberladung, Klassen 
oder Templates kann man damit nutzen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.