Forum: PC-Programmierung Unverständliche Warnung: "Integral size mismatch" mit EVC++4.0 / Windows CE


von Peter (Gast)


Lesenswert?

Hallo,

ich habe hier eine Codepassage aus einem extern eingebundenen C-Code 
(zur Ansteuerung von IO-Modulen über Ethernet), der mir beim Compilieren 
immer die folgende Warnung bring:

> integral size mismatch in argument; conversion supplied

Compiliert wird das ganze unter Microsoft Embedded Visual C++ 4.0 für 
ein Windows CE-Gerät (x86) und funktioniert auch, mich stört allerdings 
diese Warnung, deren Sinn ich nicht verstehe. Vielleicht kann mir ja 
jemand sagen, was diese Warnung auslöst (und welche "conversion" der 
Compiler "supplied") bzw. ob sie sicher ignoriert werden kann. Die mit 
Google oft gefundene Erklärung, es würde eine Klammer fehlen, trifft 
hier meiner Ansicht nach nicht zu (im Gegensatz, sogar eine zu viel) und 
sämtliche Versuche, die Klammern anders zu setzten haben auch nichts 
geholfen.

Programmausschnitt (der Fehler bezieht sich auf die letze Zeile)
1
typedef struct {
2
    INT16    nodeHandle;
3
    USIGN16  command;
4
    USIGN16  length;
5
} CTRL_BLOCK
6
7
CTRL_BLOCK *ptr;
8
USIGN32  addr;
9
10
addr = ntohs((((USIGN16 *)(ptr + 1))[0] << 16)) | ntohs(((USIGN16 *)(ptr + 1))[1]);

von Simon K. (simon) Benutzerseite


Lesenswert?

Der Term ist problematisch.
USIGN16* ergibt dereferenziert wieder einen 16Bit Wert. Den schiebst du 
um 16 nach links, was 0 ergibt. Du musst vorher auf 32 Bit erweitern.

Den Sinn verstehe ich außerdem nicht so ganz. addr braucht doch nur 16 
Bit breit zu sein. Zumindest in dem Code-Ausschnitt.

von Besserwisser (Gast)


Lesenswert?

@ Peter

Magst Du mal den Link mit dem Originalcode posten?

Der Code kommt mir auch merkwürdig vor.

ptr zeigt auf das struct
ptr + 1 setzt voraus das da irgendwo ein array von structs existiert.
((USIGN16 *)(ptr + 1)) casted auf einen Zeiger auf einen 16 bit wert. Je 
nach compiler und maschine dürfte das dann der Eintrag nodeHandle sein.
In ((USIGN16 *)(ptr + 1))[0] ist das [0] eigentlich überflüssig. Selbst 
wenn da [1] oder so stehen würde macht es eigentlich keinen Sinn 
Strukturmitglieder so zu adressieren, zumal mit "." und "->" der 
Compiler die ganze Arbeit machen würde.

von Simon K. (simon) Benutzerseite


Lesenswert?

Yep

1
 typedef struct {
2
     INT16    nodeHandle;
3
     USIGN16  command;
4
     USIGN16  length;
5
 } CTRL_BLOCK
6
 
7
 CTRL_BLOCK *ptr;
8
 USIGN32  addr;
9
 
10
 addr = ntohs((USIGN16) ptr[1].nodeHandle << 16) | ntohs(ptr[1].nodeHandle);

Sollte den gleichen Effekt haben. Beachte dass, wie schon gesagt, das 
casten des Strukturzeigers in einen USIGN16 nicht zwangsläufig das erste 
Element dereferenziert.

von Peter (Gast)


Lesenswert?

Hallo,

danke für eure Antworten. Wie es ja immer sein muss, habe ich einen 
Fehler beim rauskopieren der (falschen) Structs gemacht, bitte 
entschuldigt die entstandenen Verwirrungen. Den kompletten Code möchste 
ich ungern Posten, da ich nicht sicher bin, ob der Urheber damit 
einverstanden ist (ich habe ihn mit einem Produkt erhalten). Aber 
vielleicht ist es ja jetzt etwas klarer.

Die richtige Deklaration der Structs jetzt nochmal:
1
typedef struct {
2
    USIGN16  cmd;
3
    USIGN16  length;
4
    USIGN16  id;
5
    USIGN16  status;
6
    USIGN16  checksum;
7
} CTRL_HEAD;
8
9
typedef struct {
10
    USIGN16  result;
11
    USIGN16  errClass;
12
    USIGN16  errCode;
13
} CTRL_RES;
14
15
typedef struct {
16
    CTRL_HEAD  cnf;
17
    CTRL_RSLT  result;
18
    INT16    nodeHd;
19
    USIGN16  ctrlCmd;
20
    USIGN16  ctrlParamLength;
21
} CTRL_BLOCK;
22
23
CTRL_BLOCK *ptr;
24
USIGN32  addr;
25
26
addr = ntohs((((USIGN16 *)(ptr + 1))[0] << 16)) | ntohs(((USIGN16 *)(ptr + 1))[1]);

von Besserwisser (Gast)


Lesenswert?

@ Peter

Na gut, aber der "neue" Code hat ja dieselben Eigenschaften.
Das Problem liegt ja nicht in der Struktur, sondern in der merkwürdigen 
Anwendung von cast und Indizierung.

Es gilt also nach wie vor, was Simon (und meine Wenigkeit) gesagt hat 
(haben).

Die eigentliche Ursache, nämlich das merkwürdige casten von Daten 
unterschiedlicher Wortbreite (d.h. nämlich "integral size mismatch" ) 
hat Simon ja schon bemerkt.

von Peter (Gast)


Lesenswert?

Ok, wenn ich euch dann so richtig verstanden habe, bedeutet das:
Ich muss mich jetzt entscheiden, ob ich den Code so mit Warnung 
weiterverwenden will, und vertrauen, dass er auch das richtige tut (was 
ja der Fall zu sein scheint). Alternativ könnte ich den Zugriff auf die 
Struktur auch in die  "." und "->"-Notation umwandeln, was funktional 
keinen Unterschied machen sollte, aber für Einduetigkeit sorgen würde.

Auf jeden Fall danke für eure Hilfe!

von Simon K. (simon) Benutzerseite


Lesenswert?

Peter wrote:
> Ok, wenn ich euch dann so richtig verstanden habe, bedeutet das:
> Ich muss mich jetzt entscheiden, ob ich den Code so mit Warnung
> weiterverwenden will, und vertrauen, dass er auch das richtige tut (was
> ja der Fall zu sein scheint). Alternativ könnte ich den Zugriff auf die
> Struktur auch in die  "." und "->"-Notation umwandeln, was funktional
> keinen Unterschied machen sollte, aber für Einduetigkeit sorgen würde.
>
> Auf jeden Fall danke für eure Hilfe!

Genau. Ich jedenfalls würde den Code irgendwie in meinen 
Windows-Papierkorb verbannen, wenn ich sowas schon sehe. ;)

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.