Forum: Compiler & IDEs Hilfe zu Warnmeldung


von Mathias O. (m-obi)


Lesenswert?

hallo,

hab da mal einen sourcecode der nicht funzt:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
#define Taster_2 (PIND&(1<<PD3))
5
6
uint8_t key_pressed_1(const volatile uint8_t *inputreg, uint8_t inputbit)
7
{
8
  static uint8_t last_state = 0;
9
  if (last_state==(*inputreg&(1<<inputbit))) return 0;
10
  _delay_ms(20);
11
  last_state=(*inputreg&(1<<inputbit));
12
  return (*inputreg&(1<<inputbit));
13
}
14
 
15
uint8_t key_pressed_2(const volatile uint8_t *input)
16
{
17
  static uint8_t last_state = 0;
18
  if ( last_state == *input ) return 0; 
19
  _delay_ms(20);
20
  last_state = *input;
21
  return *input;
22
}
23
24
int main(void)
25
{
26
  DDRD = 0b11100011;
27
28
  while(1)
29
  {                
30
        if (key_pressed_1(&PIND,PD2)) PORTD ^= (1<<5);
31
    if (key_pressed_2(Taster_2)) PORTD ^= (1<<6);
32
    }
33
    return 0;
34
}

der gibt mir beim maken folgende warnmeldung raus:
main.c:31: warning: passing argument 1 of 'key_pressed_2' makes pointer 
from integer without a cast
kann mir einer dabei helfen?

von Björn R. (sushi)


Lesenswert?

>#define Taster_2 (PIND&(1<<PD3))


>uint8_t key_pressed_2(const volatile uint8_t *input)

>key_pressed_2(Taster_2)

du sagst in der Deklaration deiner Funktion, dass das Argument ein 
pointer auf uint8_t sein soll übergibst aber einen einfachen 
integer-wert. Mach mal den Stern da weg, das ist bei konstanten eh 
blödsinn...
in der restlichen Funktion natürlich jeweils auch den Stern weg.
LG, Björn

von Mathias O. (m-obi)


Lesenswert?

super funktioniert, danke!
Wozu ist denn der Stern eigentlich da, weil in der oberen Funktion muss 
er hin.

von Björn R. (sushi)


Lesenswert?

Stichwort Pointer. Das sind Variablen, die die Adresse einer anderen 
Variablen speichern. Lies dir dazu mal ein Buch über C durch! Oder 
sonstiges C-grundlagenwissen...

je nachdem, wo der Stern steht, deklariert er eine Pointervariable oder 
er ist der sogenannte Dereferenzierungsoperator(liefert also zu einem 
Pointer den Wert, der an der Adresse gespeichert ist). Das Gegenteil, 
also der Referenzierungsoperator, der die Adresse zu einer Variablen 
liefert, ist das &.

Auch in der anderen Funktion ist der Pointer Blödsinn. Bei der Übergabe 
erzeugst du die Adresse mit &, in der Funktion nimmst du dann den Wert, 
indem du mit * wieder dereferenzierst. Ein Anwendungsfall, wo er 
gebraucht würde, ist, wenn eine Variable außerhalb der Funktion diurch 
die Funktion geändert werden sollte(sogenanntes Call by Reference). Das 
ist hier aber nicht der Fall.
Lösch mal alle * in der Funktion, und beim Aufruf, also hier:
>if (key_pressed_1(&PIND,PD2)) PORTD ^= (1<<5);
löscht du das &.

Edit: Schau mal hier:
http://home.netcom.com/~tjensen/ptr/pointers.htm

LG, Björn

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Björn R. wrote:

> Auch in der anderen Funktion ist der Pointer Blödsinn.

Nein.

Wenn der Wert eines SFRs in eine Funktion geliefert wird, ist dieser 
Wert in der Funktion konstant, d.h. jedes mal, wenn man den Wert 
verwendet, ist er gleich. Und wenn man den Wert ändert, hat das keinen 
Effekt auf das SFR selbst.

Wenn man die Adresse eines SFRs verwendet, ist das komplett anders!

Vergleiche zum Beispiel folgende Funktionen
1
void wait1 (volatile unsigned char * x)
2
{
3
    while (*x);
4
}
5
6
void wait2 (unsigned char x)
7
{
8
    while (x);
9
}

Während wait1() das macht, was es soll (nämlich warten, bis sich im SFR, 
dessen Adresse in x steht, was tut) ist wait2 gleichbedeutend mit der 
optimierten Version
1
void wait2 (unsigned char x)
2
{
3
    if (x)
4
        while (1);
5
}

von Björn R. (sushi)


Lesenswert?

Und, haben wir diesen Fall hier? Nein! Also doch Blödsinn. Der Wert wird 
nur einmal abgefragt, also reicht es wenn er kopiert wird.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Björn R. wrote:
> Und, haben wir diesen Fall hier? Nein! Also doch Blödsinn. Der Wert wird
> nur einmal abgefragt, also reicht es wenn er kopiert wird.

Björn R. wrote:
> Auch in der anderen Funktion ist der Pointer Blödsinn.

In key_pressed_1() zähle ich 3 mal die Verwendung von *inputreg.
Wieviel zähltst du?

Zudem kommt es nicht darauf an, wie oft statisch darauf zugegriffen 
wird, sondern wie oft dies zur Laufzeit geschieht.

Auch wenn statisch nur 1x zugegriffen wird, kann dies zur Laufzeit zu 
vielen Zugriffen führen. Ein Beispiel ist der Zugriff innerhaln einer 
Schleife.

von Björn R. (sushi)


Lesenswert?

Guck dir doch an was die Funktion machen soll! ich bleibe dabei, es 
reicht wenn der Wert einmal bei funktionsaufruf kopiert wird. pointer 
unnötig.
Sollte die funktion in einer Schleife aufgerufen werden wird bei jedem 
funktionsaufruf der wert neu kopiert.

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.