mikrocontroller.net

Forum: Compiler & IDEs AVR-GCC warnings


Autor: Timo P. (latissimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

1) warning: array subscript has type 'char'

Bin ich beim AVR-GCC gezwungen, den subscript als int zu wählen? Mein 
SRAM platzt schon aus allen Nähten. Ich hab sogar nen Bitfeld für meine 
ganzen Flags genutzt.

2) warning: function returns address of local variable
Warum bekomme ich dazu eine Warning? MUSS/SOLL ich unbedingt eine 
globale oder eine übergebene Variable nutzen?(z.B. als char* übergeben?)
Code dazu:
const char * byte_to_binary(char byte)

{
  char binary[9]={'\0'};

  if(byte&0x01)
  strcat(binary,"1");
  else 
  strcat(binary,"0");
  return binary;
}

Danke für Antworten!

: Verschoben durch Moderator
Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du darst keine Zeiger von einer Stack variabel zurückgeben

Autor: MicroSD (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P. schrieb:
> 2) warning: function returns address of local variable
> Warum bekomme ich dazu eine Warning?

Weil die Lokale Variable vor dem Return wieder aufgeräumt/freigegeben 
wird. dein Rückgabewert ist also ein Pointer auf eine nicht mehr belegte 
Stack-Position.
Dort stehen zwar normalerweise noch die richtigen Werte, müssen aber 
nicht. => Es ist zufall, ob dein Programm funktioniert.

Ausserdem: Deine "strcat"-Schleife ist suboptimal (Komplexität O(n^2)), 
das geht ohne strcat viel besser.

Autor: Timo P. (latissimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann werde ich der fkt. einfach ein weiteres arg. vom typ char* 
verpassen und ihr dann eine ext. var mit übergeben.



Komplexität O(n^2) als alternative zu strcat sagt mir nichts....

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P. schrieb:
> Komplexität O(n^2) als alternative zu strcat sagt mir nichts....

dir fehlt noch irgendwie eine schleife, du willst ja 8bit anhängen. Was 
Timo sagen wollte ist das strcat jedesmal das ende des strings sucht und 
dann dort etwas anhängt. Das ist aber nicht sinnvoll.
du braucht dir nur die aktuell position zu merken und kannst dort direkt 
die 0 oder 1 reinschreiben und am ende eine \0. also komplett ohne 
strcat arbeiten.

Autor: Timo P. (latissimo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann mach ich es in einer Schleife, in der ich die stelle [i] anspreche. 
Dann mache ich es statisch für 8 bit vars. Den string, den ich bereit 
stellen sollte, kann ich dann immernoch mit 0x00 terminieren nach der 
Schleife.

Welchen Nachteil hat strcat denn? Ist es so rechen/Zeitintensiv?

Übrigens: Danke für eure Antworten!

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

Bewertung
0 lesenswert
nicht lesenswert
Timo P. schrieb:

> 1) warning: array subscript has type 'char'
>
> Bin ich beim AVR-GCC gezwungen, den subscript als int zu wählen? Mein
> SRAM platzt schon aus allen Nähten.

Was hat das eine mit dem anderen zu tun?

Array subscripts sind per C-Standard nun mal vom Typ "int".  Du
handelst dir insbesondere potenzielle sign extension Probleme ein,
wenn du einfach nur "char" nimmst.

Wenn schon, dann nimm uint8_t (aus <stdint.h>).

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde es so ähnlich machen...
const char * byte_to_binary(char byte)
{
  
  static char binary[9];
  for(char i=0;i<8;i++)
  {
   if (byte & 0x80)
   {
     binary[i]='1';
   }
   else
   {
     binary[i]='0';
   }
   byte = byte < 1;
  }
  binary[8]=0;
  return binary;
}

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> Ich würde es so ähnlich machen...const char * byte_to_binary(char byte)
ich weiss nicht wie gut der compiler ist, aber man kann das noch etwas 
optimieren:
const char * byte_to_binary(char byte)
{
   static char binary[9];
   char* p = binary;
   for(char i=0;i<8;i++){
    if (byte & 0x80) {
      *p='1';
    } else {
      *p='0';
    }
    byte = byte < 1;
    ++p;
   }
   *p=0;
   return binary;
 }

Autor: !p (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if (byte & 0x80) {
      *p='1';
    } else {
      *p='0';
    }
    byte = byte < 1; //FALSCH --> <<
    ++p;

Kürzer:
*(p++)=byte & 0x80 + '0';
byte<<1;


ungeprüft


Alternativ
const char * byte_to_binary(char byte)
{
   static char binary[9]="00000000";
   for(uint8_t i=0;i<8;i++,byte<<=1)
   {
      binary[i]=byte&0x80+'0';
   }
   return binary;
 }


ungeprüft

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
!p schrieb:
> Kürzer:

Kürzer, aber auch falsch (wie auch die Alternative). Oder ergibt 
womöglich '0'+128 ein Zeichen, das so ähnlich wie eine '1' aussieht?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und nochmals falsch:
static char binary[9]="00000000";
...würde nur einmal vor dem Programmstart auf "00000000" initialisiert 
und nicht für jeden Funktionsaufruf, weil eben static!

Autor: !p (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beides richtig, sorry, war in Gedanken woanders. Kann gelöscht werden.

schäm

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P. schrieb:
> 1) warning: array subscript has type 'char'
>
> Bin ich beim AVR-GCC gezwungen, den subscript als int zu wählen? Mein
> SRAM platzt schon aus allen Nähten. Ich hab sogar nen Bitfeld für meine
> ganzen Flags genutzt.

wenn schon, dann unsigned char - dann wird dein Index nicht negativ.

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

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:

> wenn schon, dann unsigned char - dann wird dein Index nicht negativ.

Oder uint8_t, wie ich oben schon vorgeschlagen habe.  Kommt letztlich
auf dasselbe raus, aber man erkennt dabei sofort die Intention, einen
kleinen Integer-Datentypen zu nutzen.  Besser wäre noch uint_fast8_t,
denn nicht auf allen Plattformen spart die zwanghafte Benutzung von
nur 8 bits auch tatsächlich Code und/oder Zeit, und auf eine exakte
Wortbreite kommt es ja hier gar nicht an.

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.