verstehe diese Compiler-Warnung nicht

Gast #2813060
Lesenswert?
• ▲
▼
Hallo,

ich habe den nachfolgenden array aus strings und möchte den jeweiligen 
Tag ausgeben können, was doch eigentlich kein Problem sein sollte:
1
char *weekDay[] = {"ERR", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
2

3
print_dbg("Heute ist ");
4
print_dbg(weekDay[1]);

Soweit funktioniert das ganze auch, aber ich bekomme komischer weise 
diese Warnung:
1
Warning      array subscript has type 'char'


Ich kann mir allerdings nicht erklären, was der Compiler hier zu meckern 
hat. Kann mir jemand einen Tipp vielleicht geben?
Lesenswert?
• ▲
▼
Nicht bei Arrays, nur bei Pointern, und das Überlaufverhalten von 
vorzeichenbehafteten Datentypen ist nicht definiert, also nicht per se 
als negativ zu sehen.

Diese in meinen Augen etwas fragwürdige Warning scheint tatsächlich Teil 
von GCC zu sein. Weshalb sie hier auslösen sollte ist jedoch unklar. 
Aber vielleicht ist der hier gezeigte Code ja nicht der eigentliche 
Code, nur "so ähnlich". Oder der relevante Teil fehlt.
Gast
Lesenswert?
• ▲
▼
A. K. schrieb:
> Diese in meinen Augen etwas fragwürdige Warning scheint tatsächlich Teil
> von GCC zu sein.

im Test tritt es aber nicht auf:
1
#include <stdio.h>
2

3
char *weekDay[] = {"ERR", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
4

5
int main()
6
{
7
   printf("Heute ist ");
8
   printf(weekDay[1]);
9

10
   return 0;
11
}

wie ist denn print_dbg definiert?
Lesenswert?
• ▲
▼
Peter II schrieb:
> im Test tritt es aber nicht auf:

Kann ja auch nicht, weil weit und breit kein Index vom Typ char zu sehen 
ist. So aber schon, und da kriegt man die Warnung dann auch (-Wall):
1
int main()
2
{
3
   char c = 1;
4

5
   printf("Heute ist ");
6
   printf(weekDay[c]);
7

8
   return 0;
9
}
Ich schrieb ja schon, dann brechbunkt hier möglicherweise den 
eigentlichen Code zwecks Demonstration stark vereinfacht und damit die 
Ursache gleich mit beseitigt hatte.
Gast
Lesenswert?
• ▲
▼
Ja stimmt, ich habe den Code vereinfachen wollen. Normaler weise schaut 
er so aus:
1
print_dbg(weekDay[ tm->tm_wday ]);

Der Wert tm_wday ist ein 8 Bit Wert von einem RTC.

Wenn ich die Zeile allerdings (dank eurer Hilfe) so abändere, ist alles 
gut:
1
print_dbg(weekDay[(int)(tm->tm_wday)]);
Lesenswert?
• ▲
▼
Stefan Ernst schrieb:
> Besser wäre es allerdings, tm_wday von vornherein einen sinnvollen
> 8-Bit-Typ zu geben, nämlich "unsigned char" oder "uint8_t".

Mit dieser Idee kommst du rund 40 Jahre zu spät. Allerdings ist der 
Unterschied bei Werten zwischen 0 und 6 nicht wirklich relevant.

Zumal für mich nicht nachvollziehbar ist, wieso negative ints gut sind 
und negative chars schlecht.
Moderator Persönliche Seite
Lesenswert?
• ▲
▼
A. K. schrieb:
> Stefan Ernst schrieb:
>> Besser wäre es allerdings, tm_wday von vornherein einen sinnvollen
>> 8-Bit-Typ zu geben, nämlich "unsigned char" oder "uint8_t".
>
> Mit dieser Idee kommst du rund 40 Jahre zu spät.

Das Feld tm_wday der struct tm gemäß C-Standard ist vom Typ
"int".

Unser TE wird also wohl irgendwie sein eigenes Süppchen kochen.

> Zumal für mich nicht nachvollziehbar ist, wieso negative ints gut sind
> und negative chars schlecht.

Ich denke nicht, dass es um negative chars schlechthin geht, aber
um mögliche Probleme bei der sign extension zu `int'.  Bei
1
char c = 240;
2

3
   ...
4
   return array[c];

könnte das nämlich zu unliebsamen Überraschungen führen, wenn das
default `char' vorzeichenbehaftet ist, und davor zu warnen ist
die Sache m. E. Wert.
Lesenswert?
• ▲
▼
A. K. schrieb:
> Stefan Ernst schrieb:
>> Besser wäre es allerdings, tm_wday von vornherein einen sinnvollen
>> 8-Bit-Typ zu geben, nämlich "unsigned char" oder "uint8_t".
>
> Für diese Idee kommst du rund 40 Jahre zu spät.

Falls du auf die struct tm der time.h hinaus willst, dort ist tm_wday 
ein int, kein char. Er verwendet also irgendwas eigenes oder 
modifiziertes, und es spricht nichts dagegen, es zu ändern.
Lesenswert?
• ▲
▼
tumb schrieb:
> Stefan Ernst schrieb:
>> Besser wäre es allerdings, tm_wday von vornherein einen sinnvollen
>> 8-Bit-Typ zu geben, nämlich "unsigned char" oder "uint8_t".
>
> Ganz und gar nicht. Der Index muss int sein, kein char - dann
> klappts auch ohne Warnung bzw. Laufzeit-Fehler.

Unsinn. Ein "unsigned char", "signed char", "int8_t" oder "uint8_t" 
würde auch keine Warnung bringen.
Moderator Persönliche Seite
Lesenswert?
• ▲
▼
A. K. schrieb:
> Jörg Wunsch schrieb:
>> signed char c = 240;
>
> Da liegt das Hase im Pfeffer. Denn eigentlich müsste er an *dieser*
> Stelle warnen.

Das "signed" hatte ich dann noch rausgeworfen.  Wenn man das
hinschreibt, nimmt der GCC es als Hinweis, dass man sich was dabei
gedacht hat ;), und warnt nicht.  Die Warnung kommt wirklich nur für
ein "unqualifiziertes" `char', und sie soll offenbar ausschließlich
darauf hinweisen, dass bei der Benutzung eines solchen als Array-Index
eine implizite Konvertierung nach `int' erfolgt mit all ihren
potenziellen Tücken.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.