Forum: Compiler & IDEs negative integer implicitly converted to unsigned type


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,

ich verbringe meinen Nachmittag mit Fehlersuche, und eine Fehlerursache 
habe ich gerade gefunden: In zwei C-Dateien ist folgendes definiert:

Datei 1:
1
extern volatile uint16_t gl_step_soll;

Datei 2:
1
volatile uint32_t gl_step_soll;

Ich nutze den ARM-GCC ( arm-none-eabi-gcc ). Daß mir der Compiler trotz 
pedantischer Flags keine Fehlermeldung geben kann, verstehe ich. Aber
offensichtlich ergibt dieser Fehler auch keine Linker-Warnung oder gar 
einen Linker-Fehler.

Warum? Kann man das ändern?

Viele Grüße
W.T.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das lässt sich nur mit sauberer Programmierung umgehen.

Die /extern/-Deklaration gehört in eine *.h-Datei, und diese muss in 
beide *.c-Dateien eingebunden werden.

Dann nämlich kann der Compiler beim Übersetzen der *.c-Datei, in der die 
Variable tatsächlich definiert wird, herausfinden, daß da ein 
Widerspruch besteht.

Beim von Dir beschriebenen Verfahren aber ist der Compiler beim 
Übersetzen beider *.c-Dateien glücklich, und der Linker bekommt nur 
einen Symbolnamen ohne Typinformationen vorgesetzt, so daß er das 
Problem nicht erkennen kann.


Anders sähe es aus, würde man die beien *.c-Dateien mit einem 
C++-Compiler übersetzen, dann nämlich erzeugt der Compiler "dekorierte 
Namen" für die Symbole, und beim Linken kracht es dann, weil die Namen 
sich unterscheiden.

von Nop (Gast)


Lesenswert?

Walter T. schrieb:

> Warum? Kann man das ändern?

GCC 6.3.0 (MingW) erkennt das, ebenso wie GCC ARM-NONE_EABI 6.3.1, 
gerade getestet. Aber nur, sofern man -flto nutzt.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Rufus Τ. F. schrieb:
> Anders sähe es aus, würde man die beien *.c-Dateien mit einem
> C++-Compiler übersetzen, dann nämlich erzeugt der Compiler "dekorierte
> Namen" für die Symbole, und beim Linken kracht es dann, weil die Namen
> sich unterscheiden.
Aber nur bei Funktionen. Variablen kann man schließlich nicht überladen, 
daher ist der Symbolname sowohl von einem "int foo;" als auch von einem 
"float foo;" beide Male einfach nur "foo". Daher findet C++ hier auch 
keine Fehler.

von Carl D. (jcw2)


Lesenswert?

Nop schrieb:
> Walter T. schrieb:
>
>> Warum? Kann man das ändern?
>
> GCC 6.3.0 (MingW) erkennt das, ebenso wie GCC ARM-NONE_EABI 6.3.1,
> gerade getestet. Aber nur, sofern man -flto nutzt.

Weil mit LTO (stark vereinfacht dargestellt) alle .c-Files erst mal 
geparst werden und der Linker dann den Compiler ruft, um das ganze als 
eine einzige Compilation Unit zu behandeln. Eigentlich um übergreifend 
zu optimieren, aber der Zwischencode enthält auch genügend 
Typinformation, um diese Art von Fehlern zu finden.

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Niklas G. schrieb:
> Aber nur bei Funktionen.

Da hast Du natürlich auch wieder recht.

Bleibt also nur das saubere Programmieren übrig. Anstrengend, kann nicht 
ein Automat die Fehler wegmachen?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Rufus Τ. F. schrieb:
> Bleibt also nur das saubere Programmieren übrig.
So ist es... Prototypen gehören in Header-Dateien (außer die 
Funktion/Variable wird nur innerhalb einer Source-Datei definiert & 
genutzt). Wobei die Nutzung globaler Variablen, dann auch noch über 
mehrere Dateien hinweg, ohnehin "kontrovers" ist.

Rufus Τ. F. schrieb:
> Anstrengend, kann nicht ein Automat die Fehler wegmachen?
DWIM? ;-) Aber ja, Java-Programmierer haben es einfacher, die brauchen 
keine Header und Forward Declarations...

: Bearbeitet durch User
von Kaj G. (Firma: RUB) (bloody)


Lesenswert?


von Walter T. (nicolas)


Lesenswert?

Rufus Τ. F. schrieb:
> Das lässt sich nur mit sauberer Programmierung umgehen.

Das habe ich schon befürchtet.

Danke auch für den Link auf den "Grundlagenartikelpost" von J. Lay.

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.