Forum: Compiler & IDEs Array an Funktion übergeben (Pointer)


von Ben H. (belchy)


Lesenswert?

Hallo zusammen,

ich habe schon Versucht in Google eine Lösung für mein Problem zu 
finden, bin dort jedoch auf nichts brauchbares gestoßen. Deswegen hoffe 
ich, dass mir hier jemand helfen kann.

Ich programmiere zur Zeit auf einem Atmega644 in AVR Studio 4 die UART 
Schnittstelle (was bisher auch relativ gut funktioniert hat).
Jedoch habe ich jetzt ein Problem mit meiner Senden-Funktion.
Per RX-Interrupt versuche ich mehrere empfangene Zeichen in einem Buffer 
zu speichern (char Array) und diese dann meiner Senden Funktion zu 
übergeben. Diese soll dann eben genau den Empfangenen Array per UART 
wieder zurückschicken.

Der Compiler meldet mir aber folgende Warnung:
warning: passing argument 1 of 'send_String' discards qualifiers from 
pointer target type

Folgendes sind die relevanten Code-Abschnitte:

Buffer definition:
1
unsigned char rx_buffer[100];


Sende-Funktion:
1
void send_String(char *string){
2
  while(*string){
3
    send_Char(*string++);
4
  }
5
}


RX Interrupt: (ein Zeichen wir so lange in rx_buffer gespeichert, bis 
0xFD emfpangen wird)
1
ISR(USART0_RX_vect){
2
  static unsigned char i = 0;
3
  PORTB = PORTB | 0x02;
4
  if(UDR0 != 0xFD){
5
    rx_buffer[i] = UDR0;
6
    i++;
7
  }
8
  else{
9
    uart_msg_complete = 1;
10
    i = 0;
11
  }
12
}

Zuletzt noch die Main-Funktion:
1
int main(void){
2
  USART_Init(BAUDRATE);
3
  sei();
4
  while(1){
5
    if(uart_msg_complete){
6
      send_String(&rx_buffer[0]);  
7
      uart_msg_complete = 0;
8
    }
9
  }
10
  return 0;
11
}

Bei der Zeile send_String(&rx_buffer[0]); tritt die Warnung auf.
Ich habe schon mehrere Möglichkeiten getestet. Z.B. mit einem 
Hilfspointer:
1
buffer_pointer = &rx_buffer[0];
und dann:
1
send_String(buffer_pointer);
Jedoch hat dies auch nicht funktioniert.

Ich hoffe einer von euch kann mir bei meinem Problem helfen.

Danke schon mal im Vorraus.

Ben

von asdf (Gast)


Lesenswert?

send_String(&rx_buffer[0]); --> send_String(&rx_buffer);

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Ben Ha schrieb:
1
unsigned char rx_buffer[100];
1
void send_String(char *string)
1
send_String(&rx_buffer[0]);

Wie der Compiler bereits gesagt hat, sind Parameter und erwarteter Typ 
nicht (notwendigerweise) kompatibel. Der qualifier (unsigned) wird 
daher vom Compiler verworfen.

--
Marcus

von Klaus F. (kfalser)


Lesenswert?

Auf die Schnelle würde ich sagen dass es damit zusammenhängt, dass
RX_Buffer als unsigned char definiert ist, aber sendstring ein char 
array  erwartet.

von guest (Gast)


Lesenswert?

Dein Array ist ein unsigned char Array.

Ben Ha schrieb:
> unsigned char rx_buffer[100];

mit

Ben Ha schrieb:
> send_String(&rx_buffer[0]);

übergibst Du also einen Zeiger auf einen unsigned char.
Deine Funktion

Ben Ha schrieb:
> void send_String(char *string){
>   while(*string){
>     send_Char(*string++);
>   }
> }

erwartet aber einen Zeiger auf einen char, und nicht auf einen unsigned 
char.

Daher die Warnung des Compilers

von Stefan E. (sternst)


Lesenswert?

"discards qualifiers" hat nichts mit signed oder unsigned zu tun. Sehr 
wahrscheinlich belügt uns der OP bezüglich der Deklaration von 
rx_buffer. Da dürfte in Wirklichkeit ein "volatile" davor stehen. Und 
das ist dann der "qualifier" der beim Aufruf der Funktion "discarded" 
wird.

von Rolf Magnus (Gast)


Lesenswert?

Es gibt nur zwei solche qualifiers, nämlich volatile und const. signed 
und unsigned sind keine qualifiers, sondern type modifiers.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> Es gibt nur zwei solche qualifiers, nämlich volatile und const. signed
> und unsigned sind keine qualifiers, sondern type modifiers.

Rolf und Stefan haben natürlich Recht. Mein gcc-4.5.2 gibt übrigens den 
genauen Grund in der nächsten Zeile des logs aus:
1
uc_239251.c:14:5: warning: passing argument 1 of 'send_String' discards qualifiers from pointer target type
2
uc_239251.c:4:6: note: expected 'char *' but argument is of type 'volatile unsigned char *'
Dazu musste ich tatsächlich ein volatile verwenden.

--
Marcus

von Ben Ha (Gast)


Lesenswert?

Zuerst einmal danke für die Hilfe. Ich hatte tatsächlich ein volatile 
vor der Deklaration stehen. Fragt mich nicht wie ich das vergessen bzw. 
übersehen konnte. Damit wäre das Problem behoben :)

Ein weiteres Problem war unsigned <---> signed, welches erneut eine 
Warnung gab, nachdem das vorherige Problem gelöst war.

Aber warum bringt der Compiler eine Warnung, wenn ich volatile verwende? 
Dies sagt doch eigentlich nur aus, dass die Variable vom Compiler nicht 
"wegoptimiert" werden soll. Oder liege ich da falsch?

von Oliver (Gast)


Lesenswert?

Ben Ha schrieb:
> Dies sagt doch eigentlich nur aus, dass die Variable vom Compiler nicht
> "wegoptimiert" werden soll. Oder liege ich da falsch?

volatile sagt nicht aus, daß die Variable nicht wegoptimiert werden 
darf, sondern daß sie sich ohne Wissen des Compilers verändern kann, und 
sie daher vor JEDER Verwendung neu aus der Speicheradresse gelesen 
werden muß. Ein Nebenefekt ist dann der, daß sie nicht wegoptimiert 
wird.

Die Warnung kommt halt, weil die qualifiers nicht übereinstimmen.

Oliver

von Peter II (Gast)


Lesenswert?

Die frage ist ob das volatil an der richtigen Stelle steht. Dann was 
ändert sich denn? Der Zeiger oder das wohin der Zeiger zeigt?

von Rolf Magnus (Gast)


Lesenswert?

Ben Ha schrieb:
> Aber warum bringt der Compiler eine Warnung, wenn ich volatile verwende?

Weil das volatile bei der Referenzierung verlorengeht.
Beispiel:
1
int main()
2
{
3
    volatile int i;
4
    int* p = &i;
5
6
    // i ist hier volatile, *p, was das gleiche wie i ist, aber nicht.
7
}

Du behandelst die Variable i in diesem Fall bei direkter Verwendung als 
volatile, während jeder Zugriff über den Zeiger so erfolgt, als wäre sie 
nicht volatile. Da das in der Regel nicht so gedacht ist, warnt der 
Compiler dich.

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.