Forum: Compiler & IDEs AVR-GCC warnings


von Timo P. (latissimo)


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:
1
const char * byte_to_binary(char byte)
2
3
{
4
  char binary[9]={'\0'};
5
6
  if(byte&0x01)
7
  strcat(binary,"1");
8
  else 
9
  strcat(binary,"0");
10
  return binary;
11
}

Danke für Antworten!

: Verschoben durch Moderator
von Peter (Gast)


Lesenswert?

du darst keine Zeiger von einer Stack variabel zurückgeben

von MicroSD (Gast)


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.

von Timo P. (latissimo)


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

von Peter (Gast)


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.

von Timo P. (latissimo)


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!

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


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

von Peter (Gast)


Lesenswert?

Ich würde es so ähnlich machen...
1
const char * byte_to_binary(char byte)
2
{
3
  
4
  static char binary[9];
5
  for(char i=0;i<8;i++)
6
  {
7
   if (byte & 0x80)
8
   {
9
     binary[i]='1';
10
   }
11
   else
12
   {
13
     binary[i]='0';
14
   }
15
   byte = byte < 1;
16
  }
17
  binary[8]=0;
18
  return binary;
19
}

von Peter II (Gast)


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:
1
const char * byte_to_binary(char byte)
2
{
3
   static char binary[9];
4
   char* p = binary;
5
   for(char i=0;i<8;i++){
6
    if (byte & 0x80) {
7
      *p='1';
8
    } else {
9
      *p='0';
10
    }
11
    byte = byte < 1;
12
    ++p;
13
   }
14
   *p=0;
15
   return binary;
16
 }

von !p (Gast)


Lesenswert?

1
if (byte & 0x80) {
2
      *p='1';
3
    } else {
4
      *p='0';
5
    }
6
    byte = byte < 1; //FALSCH --> <<
7
    ++p;

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


ungeprüft


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


ungeprüft

von Stefan E. (sternst)


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?

von Peter (Gast)


Lesenswert?

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

von !p (Gast)


Lesenswert?

Beides richtig, sorry, war in Gedanken woanders. Kann gelöscht werden.

schäm

von Klaus W. (mfgkw)


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.

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


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.

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.