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


von Sam .. (sam1994)


Lesenswert?

Hi

ich versteh das echt nicht. Ich hab hier diesen Code mit folgender 
Funktion:
1
int main(void) 
2
{
3
    uint16_t bonus = 0;
4
    Add(&bonus,1,5999);
5
}
6
7
void Add(uint32_t* source, int32_t add, uint32_t max)
8
{
9
    int32_t tmp = *source + add;
10
    if(tmp >= 0 && tmp <= max)
11
        *source = tmp;
12
}

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.

von sebastians (Gast)


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:
1
int main(void) 
2
{
3
    uint16_t bonus = 0;
4
    ...
5
    {
6
        uin32_t hilfsvariable = bonus;
7
        Add(&hilfsvariable,1,5999);
8
        if(hilfsvariable <= 0xFFFF)
9
        {
10
            bonus = hilfsvariable;
11
        }
12
        else
13
            ...
14
    }
15
}

Vielleicht macht es auch Sinn, das Ergebnis so zurückzuliefern:
1
uint32_t Add(uint32_t source, int32_t add, uint32_t max);
2
3
int main(void) 
4
{
5
    uint16_t bonus = 0;
6
    bonus = Add(bonus,1,5999);
7
}
8
9
uint32_t Add(uint32_t source, int32_t add, uint32_t max)
10
{
11
    int32_t tmp = source + add;
12
    if(tmp >= 0 && tmp <= max)
13
        return tmp;
14
    else
15
        return source;
16
}

PS:
1
tmp >= 0
 ist immer TRUE.

von Rolf Magnus (Gast)


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.
1
    uint32_t tmp = bonus;
2
    Add(&tmp,1,5999);
3
    bonus = tmp;

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

von Sam .. (sam1994)


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?

von Sam .. (sam1994)


Lesenswert?

Es kommt trotzdem die Warnung

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

Was heißt das?

von Karl H. (kbuchegg)


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

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Sam .. (sam1994)


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.

von Rolf Magnus (Gast)


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++.

von Sam .. (sam1994)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Rolf Magnus (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.