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?
#2813112
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 #2813115
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?
#2813122
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 #2814013
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)]);
#2814623
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 #2814637
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.
#2814641
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.
#2814647
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 #2814741
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren