Forum: Offtopic [C] Böse Falle: Datentyp korrekt angegeben, falscher verwendet


von Stefan F. (Gast)


Lesenswert?

Karl K. schrieb:
> Dann bleib halt in Deiner kleinen C-Welt. NMP.

C füllt in meiner Welt nur einen winzig kleinen Teil aus. Ich arbeite 
ganz woanders und ich habe viele Programmiersprachen kommerziell 
eingesetzt. Da war lange Zeit auch dein geliebtes Pascal bei.

Ich liebe inzwischen eine Frau.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Ich liebe inzwischen eine Frau.

Damit hast Du diese reichlich überflüssige Diskussion eigentlich sehr, 
sehr schön auf den Punkt gebracht.

Menschen sind viel wichtiger als Programmiersprachen.

von (prx) A. K. (prx)


Lesenswert?

Thomas M. schrieb:
> wieso landen solche Diskussionen eigentlich immer unter in Offtopic?

Um c-hater kalt zu stellen.

von Rolf M. (rmagnus)


Lesenswert?

Karl K. schrieb:
> Stefanus F. schrieb:
>> Wenn du eine
>> Anwendung statisch linkst, sind die Libraries mit in der *.exe Datei
>> drin. Das kann C/C++ allerdings ebenso.
>
> Ja, aber bei Qt darfst Du das halt nicht, wenn Du die GPL beachtest.

Darfst du schon. Dein Programm muss dann halt auch unter GPL stehen, 
oder du musst eine kommerzielle Lizenz kaufen.

> Zumindest hab ich das so verstanden, als ich mir das damals angeschaut
> habe. Da muss die Qt-Lib dynamisch gelinkt und immer mitgeliefert werden
> oder auf dem System installiert sein.

Ich sehe jetzt nicht, wo das Problem liegt, wenn in dem Verzeichnis 
neben dem Programm noch ein paar Libs liegen.

Stefanus F. schrieb:
> Diskutiere mal mit dem TO, um welche Programmiersprache es hier geht.

Der Betreff beginnt mit dem Namen der Sprache, um die es geht.

Rufus Τ. F. schrieb:
> Stefanus F. schrieb:
>> Ich liebe inzwischen eine Frau.
>
> Damit hast Du diese reichlich überflüssige Diskussion eigentlich sehr,
> sehr schön auf den Punkt gebracht.
>
> Menschen sind viel wichtiger als Programmiersprachen.

Allerdings ist ist der Zweck dieses Forums nicht die Diskussion über 
Menschen.

: Bearbeitet durch User
von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

findet eigentlich noch jemand das jemand mal den Mod melden sollte?!
Wieso landet so ein Thema bitte in Forum: Offtopic??
Die Kompetenz als Moderator sollte hier doch stark angezweifelt 
werden...

von Karl K. (karl2go)


Lesenswert?

Thomas M. schrieb:
> Die Kompetenz als Moderator sollte hier doch stark angezweifelt
> werden...

Lass mich raten: Du bist neu hier im Forum?

von Stefan F. (Gast)


Lesenswert?

Thomas M. schrieb:
> findet eigentlich noch jemand das jemand mal den Mod melden sollte?

Was denkst du, wer den Thread dorthin verschoben hat? Die mutmassliche 
Begründung wurde auch schon genannt.

von Mark B. (markbrandis)


Lesenswert?

Thomas M. schrieb:
> findet eigentlich noch jemand das jemand mal den Mod melden sollte?!
> Wieso landet so ein Thema bitte in Forum: Offtopic??
> Die Kompetenz als Moderator sollte hier doch stark angezweifelt
> werden...

Das macht man, um einen Thread "elegant" für nicht angemeldete Benutzer 
zu sperren.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

und wenn Kritik am Moderator geübt wird..damit es nicht eskaliert..er 
wird es nie lernen...und da wundert er sich über den Uensurheini

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Über den Zensurheini wundert sich niemand mehr, ausser er selbst. Dass 
der Mann krank ist und Hilfe benötigt, ist mehr als offensichtlich.

von Le X. (lex_91)


Lesenswert?

Och ne, müsst ihr den Programmiersprachen-Kleinkrieg unbedingt am 
Sonntag führen?
Das wär die perfekte Zwischendurchlektüre für die Arbeit gewesen.
Hoffentlich gibts den Thread morgen noch.

von Axel S. (a-za-z0-9)


Lesenswert?

Thomas M. schrieb:
> "Ich habe das Gefühl, dass du über Arbeitsmittel herziehst, die du gar
> nicht kennst."
> Du meinst wie die C Leute bei Pascal  Delphi Lazarus?
> Die ja nur die Schulversion 1.0 kennen?

PASCAL ist eine reine Lehrsprache, unter diesem Namen gibt es gar keine 
Implementierung für den produktiven Einsatz. Die kanonische PASCAL 
Implementierung für den produktiven Einsatz ist Turbo-Pascal und das war 
ein Rohrkrepierer, weil es einzig auf einer Plattform (x86) und unter 
einem Betriebssystem (Win/DOS) verfügbar war [1]. Delphi ist der 
(glücklose) Nachfolger von Turbo-Pascal. Lazarus ist gar keine 
Programmiersprache, sondern eine IDE rund um Free Pascal. Letzteres ist 
die eine, leider viel zu spät erschienene Implementierung von Pascal, 
die plattformübergreifend verwendbar wäre (wenn man es haben wöllte).

Ich habe im Lauf meiner Programmierer-Karriere auch mal eine Zeit mit 
Turbo-Pascal verbracht und muß sagen, daß es für seine Zeit wirklich 
fortschrittlich war. OK, der Compiler hat schrottigen Code erzeugt. 
Dafür war er rattenschnell. Und die IDE hat gepaßt. Und es gab Libraries 
für alles Wichtige. Und der Turbo-Debugger war richtig(!) Klasse.

Trotzdem hing man an der bek(n)ackten Segmentierung des x86 fest und 
konnte entweder >64KB Code oder Datenstrukturen >64KB haben (aber 
nicht beides). Und auf (damals) fetter Hardware mit 64MB RAM oder mehr 
lief das Dingens gar nicht. Windows übrigens auch nicht. Da war es AIX 
(Rechnerraum II auf dem Campus gesponsort von IBM) oder HP-UX. Und 
später Linux. Und die einzige Programmiersprache, die da out-of-the-box 
lief, und sogar noch überall den gleichen Quellcode akzeptierte, war C. 
Das war ein riesiger FORTSCHRITT gegenüber Turbo-Pascal.

Also erzähl mir nichts davon, wer hier nicht über den Tellerrand 
schauen kann. Oh. Und wenn dir C nicht paßt, dann verwende halt eine der 
Alternativen. Java (stinkt). C# (Monokultur, wie weiland TP). Oder 
meinetwegen Ada, Erlang, Lisp, Rust. Ist ja nicht so, daß es keine 
Auswahl gäbe.

Aber hör auf damit, anderen Leuten die Werkzeuge madig zu machen, deren 
Verwendung du nicht beherrschst.


[1] ja, ok. TP 3.0 hatte ich auch mal eine Weile unter den Fingern. Auf 
einem BC5120 und CP/A. Auch ein dead-end. Immerhin mußte man sich keine 
Gedanken um ein Speichermodell machen, denn der Adreßraum war nur 
64KB. Code und Daten.

: Bearbeitet durch User
von Uhu U. (uhu)


Lesenswert?

Axel S. schrieb:
> C# (Monokultur, wie weiland TP)

C# gibts auch unter Linux.

von Percy N. (vox_bovi)


Lesenswert?

Uhu U. schrieb:
> Axel S. schrieb:
>> C# (Monokultur, wie weiland TP)
>
> C# gibts auch unter Linux.

Delphi gab es dafür auch, hieß nur anders.

von Karl K. (karl2go)


Lesenswert?

Axel S. schrieb:
> Delphi ist der
> (glücklose) Nachfolger von Turbo-Pascal.

Möööp. Delphi ist die Entwicklungsumgebung von Borland für ObjectPascal. 
Emberacado hätte nur gerne, dass die Sprache auch Delphi heisst.

> ... Free Pascal. Letzteres ist
> die eine, leider viel zu spät erschienene Implementierung von Pascal

1994: 2GB Daten verwalten
1998: Win32-Unterstützung
2000: FreeBSD-Unterstützung
2003: Linux-Unterstützung
2004: MacOS-Unterstützung

Ich gebe ja zu, leider ist FreePascal die ganzen Jahre auch an mir 
vorbeigegangen. Aber zu behaupten, es wäre "leider viel zu spät 
erschienen" - nur weil es keine Z4 Implementierung gab...

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

@Autor: Axel S. (a-za-z0-9)
dafür das Pascal eine reine Lehrsprache ist, ist der Altiumdesigner aber 
recht erfolgreich damit geschrieben..und Damals Nero oder der 
Totalcommander etc pp..
Delphi/Pascal gibts natürlich auf unter Linux..sowohl vom Emercadeo als 
auch von Freepascal.
Niemand bestreitet das damals Borland den Übergang zu Windows vermasselt 
hatte..aber das ist schon ewig her, seit dem hat sich viel geändert.

Lol..wer macht den C madig?  Es ist halt ein totaler Krampf..das ist 
Fakt.
Wieso fühlst Du dich deshalb persönlich angegriffen?
Man kann doch sagen das man es auch selber Kacke findet, aber es einige 
Vorteile für dich bietet, die es für dich unverzichtbar machen.
Das gilt aber für sehr viele andere nicht..für die überwiegt einfach der 
Stinkfaktor.
Du magst ja offenbar auch kein Pascal ..so what?! deshalb kann man sich 
dennoch über Unzulänglichkeiten einzelner Sprachen ärgern und wie 
bereits von anderen erwähnt, hat C etliche davon, und ja, sicher wirst 
Du auch in Pascal welche finden, aber halt andere!
Und vieles von dem was Du an Pascal bemängelst gilt heute doch gar nicht 
mehr.
C hatte damals auch noch erheblich mehr Unzulänglichkeiten als heute, 
die auch nach und nach ausgebügelt wurden..wo ist also das 
Problem..beide Sprachen haben sich entwickelt, PAscal deutlich mehr, da 
es aber auch mehr aufzuholen hatte..gilt vieles von den damaligen 
Erfahrungen nicht mehr

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Axel S. schrieb:
> OK, der Compiler hat schrottigen Code erzeugt. Dafür war er rattenschnell.

Und genau das war bei uns in der Schule damals wichtig, denn die 
Computer dort hatten keine Festplatte. Man musste zuerst DOS booten, 
dann die Diskette A mit Pascal und Diskette B mit den eigenen 
Quelltexten einlegen.

bei dieser HW war wichtig, dass man danach die DOS Diskette nicht mehr 
oft benötigte und dass der Compiler schnell ist, sonst war die 
Doppelstunde vorbei, bevor man etwas zustande brachte. Zu dieser zeit 
hatte auch kaum jemand einen PC zu hause um es dort vorzubereiten bzw. 
nachzuarbeiten.

Will sagen: Für die damalige Zeit war Turbo Pascal die bestmögliche 
Wahl.

von Karl K. (karl2go)


Lesenswert?

Stefanus F. schrieb:
> Und genau das war bei uns in der Schule damals wichtig, denn die
> Computer dort hatten keine Festplatte...

Haha, Opa erzählt vom Krieg... Ich kenn das zwar auch noch so vom Amiga, 
aber ich würde das AmigaBasic jetzt nicht zur Grundlage meiner Bewertung 
von Programmiersprachen machen.

Die aktuelle Lazarus+FPC Stable ist 3.3GB groß, inklusive der Sourcen 
und halt Crosscompiler für Linux und Linux Arm, Android.

von Einer K. (Gast)


Lesenswert?

Thomas M. schrieb:
> Wieso landet so ein Thema bitte in Forum: Offtopic??

Wegen genau diesem Glaubenskrieg.

So endest es immer...
Fruchtlos.

Küchenpsychologie:

Zwei diametral gegensätzliche Möglichkeiten, es gibt!

Erstens:
Man regt sich über die Unzulänglichkeiten von irgendwas/irgendwem auf, 
was man nutzen muss. Aber da es keine Alternative dazu gibt, 
wird/erscheint man krank.
Siehe C-Hater.

Zweitens:
Man arrangiert sich damit. z.B. in dem man sich das Zeugs schön redet. 
Dieses ermöglicht ein zufriedenes/gesundes Leben, und eine erfolgreiche 
Arbeit damit.


Das ist die Wahl: Krank oder gesund.
Die Entscheidung findet im Kopf statt.
Bei jedem einzelnen.
Und ja, Selbstkonditionierung ist eine menschliche Eigenschaft.


Das alles geht auch ganz ohne Priester.

----------------

Thomas M. schrieb:
> Es ist halt ein totaler Krampf..das ist Fakt.

Kennst du das Lied: https://www.youtube.com/watch?v=X94ZM-paqIc ?
Das zeigt den richtigen Umgang mit Problemen.

Oder auch Hazel Brugger, hat die GEZ mal verwertet:
https://www.youtube.com/watch?v=bCxXLMtklfQ

von Karl K. (karl2go)


Lesenswert?

Arduino Fanboy D. schrieb:
> Man arrangiert sich damit. z.B. in dem man sich das Zeugs schön redet.
> Dieses ermöglicht ein zufriedenes/gesundes Leben, und eine erfolgreiche
> Arbeit damit.

Nope. Schönreden ermöglicht gerade kein erfolgreiches Arbeiten, weil man 
auf dem ineffizienten Kram hängenbleibt.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

was hat derf Glaubenskrieg damit zu tun?!
Schau dir dei Diskussion mal an..das Thema wurde sachlich aund 
ausführlich ebsprochen erst als es durch war wurden noch nebenbei 
Gespräche geführt..das hat aber nicht dem dem Rest des Threads zu 
tun..Es ist mir völlig unverständlich wie manche Mods heir agieren 
dürfen

von Einer K. (Gast)


Lesenswert?

Karl K. schrieb:
> Nope. Schönreden ermöglicht gerade kein erfolgreiches Arbeiten, weil man
> auf dem ineffizienten Kram hängenbleibt.

Wenn man die freie Auswahl hat...
Aber das ist halt nicht immer gegeben.

Arduino Liebhaber werden sich auf C++ konzentrieren müssen.
Die meisten anderen µC Programmierer werden auf C angewiesen sein.
Die beiden Sprachen bieten eine breite Codebasis für µC.

Assembler mal außen vor. Denn es ist weder portabel, noch frei von 
Fußangeln.
Die anderen Sprachen sind einfach nur Exoten auf µC.


-----

Wenn man keinen Einfluss auf die Umstände hat, kann man nur an der 
eigenen Einstellung arbeiten.

Und genau diese Einstellung entscheidet, ob man dabei gesund bleibt, und 
erfolgreich damit arbeitet.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Thomas M. schrieb:
> Schau dir dei Diskussion mal an..das Thema wurde sachlich aund
> ausführlich ebsprochen

Deine Wahrnehmung ist, gelinde gesagt, getrübt.

von Karl K. (karl2go)


Lesenswert?

Arduino Fanboy D. schrieb:
> Arduino Liebhaber werden sich auf C++ konzentrieren müssen.

Im FreePascal Forum sind ne Menge Arduino Liebhaber, die Arduino mit 
Pascal programmieren. Tellerrand.

Arduino Fanboy D. schrieb:
> Die anderen Sprachen sind einfach nur Exoten auf µC.

Ach? Ist das so? Weil Du nur noch Bascom kennst?

Von Ada bis MicroPython gibts da mehr, als Du sinnvoll ausprobieren 
kannst.

von Karl K. (karl2go)


Lesenswert?

Thomas M. schrieb:
> Es ist mir völlig unverständlich wie manche Mods heir agieren
> dürfen

Nana, Du bist noch nicht lange hier, oder? Das ist doch harmlos, im 
Raspberry Forum wärst Du schon rausgeflogen, wenn Du was gegen die 
Lieblingsprogrammiersprache des Mods gesagt hättest. BTDT, zweimal.

von Le X. (lex_91)


Lesenswert?

Karl K. schrieb:
> Von Ada bis MicroPython gibts da mehr, als Du sinnvoll ausprobieren
> kannst.

... und sind Exoten bzw. werden nur für Nischenanwendungen eingesetzt.
Aber ja, geben tut es sie und funktionieren tun die, in ihrer jeweiligen 
Domäne, wohl auch gut.

: Bearbeitet durch User
von Karl K. (karl2go)


Lesenswert?

Le X. schrieb:
> ... und sind Exoten bzw. werden nur für Nischenanwendungen eingesetzt.

Nur weil Dir nicht jeder auf die Nase bindet, dass er nicht C einsetzt?

von Le X. (lex_91)


Lesenswert?

Karl K. schrieb:
> Nur weil Dir nicht jeder auf die Nase bindet, dass er nicht C einsetzt?

Ich werd mich an deinen Fanboy-Diskussionen nicht beteiligen.
Ich habe keine emotionale Beziehung zu irgendeiner Programmiersprache, 
ich verdien damit lediglich mein Geld.

Freu dich doch einfach dass du ein Exot bist, sei stolz drauf.
Mainstream bzw. Industriestandard kann jeder ;-)

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Thomas M. schrieb:
> auch sowas verursacht in Pascal einen Fehler
> 2);source.pas(13,9) Warning: range check error while evaluating
> constants

Warnung, nicht Fehler.

> in C kommt raus..
> -5536
> Fehlermeldung von C....KEINE!

Alle gängigen C-Compiler können ebenfalls eine Warnung erzeugen. 
Außerdem hat das Ein- oder Ausschalten der Warnungen nichts mit der 
Sprache an sich zu tun, es ist eine Eigenschaft der jeweiligen Toolchain 
und der Konfiguration des jeweiligen Builds.

Du tust Deiner Sache überhaupt keinen Gefallen (das Gegenteil ist der 
Fall) wenn man den Eindruck gewinnt daß Du auf solche lächerlichen 
Nebelkerzen zurückgreifen mußt um irgendein ein Pro-Argument für Pascal 
(oder Contra-Argument gegen C) vorbringen zu können, der Blödsinn da 
oben ist einfach zu durchschauen und jede Oma kann ihn entkräften und 
ist überhaupt kein Argument für oder gegen irgendwas.

Wenn Du ernstzunehmende Argumente vorbringen willst mußt Du die 
wirklichen Unterschiede der jeweiligen Sprachen und deren Vor- oder 
Nachteile herausarbeiten, dazu muß man aber weitaus tiefer graben (oder 
die einschlägige Literatur zu dem Thema studieren) und das was man dabei 
hervorholt muß man selber verstehen und klar definieren und abgrenzen 
können, nicht mit solchem oberflächlichen Wischiwaschi-Blödsinn 
herumwedeln wie die Default-Warneinstellungen irgendeines konkreten 
Compilers, das sagt absolut nichts über die Eigenschaften der Sprache 
aus.

: Bearbeitet durch User
von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

sorry..genau DAS ist nicht Wischi Waschi..oder an den HAren herbei 
gezogen!
Eine klare Fehlermeldung zu gar keiner Fehlermeldung IST!! berechtigte 
Kritik

von Bernd K. (prof7bit)


Lesenswert?

Thomas M. schrieb:
> Eine klare Fehlermeldung zu gar keiner Fehlermeldung IST!! berechtigte
> Kritik

Beide Compiler erzeugen keinen Fehler sondern sie erzeugen beide 
eine klare Warnung. Was sagt dieser Umstand jetzt nochmal konkret über 
den Unterschied zwischen den beiden Sprachen aus?

: Bearbeitet durch User
von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

eben NICHT!!
in C kommt keine Warnung,d a kommt absolut nichts..darum geht es hier 
Seitenweise!!
PACAL gibt aber eine Warnung...Fehlermeldung ist kackegal..es geht 
daraum das Du auf einen Schnitzer hingewisen wirst..wie Du das jetzt 
bezeichnen willst  ist albern darüber zu diskutieren.
C lässt es durchgehen und gibt ein falsches Ergebnis, Pascal warnt vor 
einem zu großen Wert der einen Fehler verursachen wird.
Schau die Quellcode Beispiele hat,..ist alles Seitenlang durchgekaut.
Und wenn Du BEIDE Compiler so einstellt das bei eienr Warnung nicht 
compiliet wird..
Gibt PASCAL auf eine FEHLERMELDUNG und C NICHTS ausser einen BUG!!
So zufrieden?!

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Thomas M. schrieb:
> Lol..wer macht den C madig?  Es ist halt ein totaler Krampf..

Damit beantwortest du deine Frage gleich selbst.

> das ist Fakt.

Nein, es ist deine Meinung. Viele halten ihre eigene Meinung für Fakten, 
weil sie es nicht schaffen, diese beiden Dinge sauber auseinander zu 
halten.
Das ist kritisch, weil diejenigen damit implizit jegliche andere Meinung 
für ungültig erklären.

von Bernd K. (prof7bit)


Lesenswert?

Thomas M. schrieb:
> C lässt es durchgehen und gibt ein falsches Ergebnis, Pascal warnt

Weder C noch Pascal tun irgendwas. Sie sind lediglich Sprachen, 
abstrakte Definitionen von Grammatik und Syntax, niedergeschrieben auf 
irgendeinem Papier.

Konkrete Compiler tun etwas und die gängigen Compiler für C die man 
heutzutage benutzt können da genauso eine Warnung anzeigen wie Dein 
Pascal-Compiler. Und bei beiden Compilern kann man die ganzen Warnungen 
auch alle ausschalten und ignorieren. Kein Unterschied.

von Rolf M. (rmagnus)


Lesenswert?

Thomas M. schrieb:
> eben NICHT!!
> in C kommt keine Warnung,d a kommt absolut nichts..darum geht es hier
> Seitenweise!!

Du willst es nicht begreifen? Nicht "in C", sondern bei deinem 
Compiler mit deinen Compiler-Einstellungen kommt keine Warnung. C 
verbietet Warnungen nicht!
Bei mir warnt der Compiler da. Willst du jetzt behaupten, es sei deshalb 
kein C-Compiler?

von Einer K. (Gast)


Lesenswert?

Karl K. schrieb:
> Ach? Ist das so? Weil Du nur noch Bascom kennst?
>
> Von Ada bis MicroPython gibts da mehr, als Du sinnvoll ausprobieren
> kannst.

Statt Argumente, persönliche Anmache.

Ich sachs ja: So werden Glaubenskriege geführt.
Priestertum...

Le X. schrieb:
> Ich habe keine emotionale Beziehung zu irgendeiner Programmiersprache,
> ich verdien damit lediglich mein Geld.
Das halte ich für eine wesentlich gesündere Einstellung.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

@Rolf M
"Du willst es nicht begreifen?"
Nö, Du willst es nicht akzeptieren..Es waren die Warnmeldungen 
eingeschaltet in C!!
"Bei mir warnt der Compiler da. Willst du jetzt behaupten, es sei 
deshalb
kein C-Compiler?"


HAst Du meine Links/Codebeispiele eigentlich gesehen?!?
In 3 verschiedenen C Compilern passiert absolut nichts!
In d und Pascal schon!

Anstatt nur rumzuposaunen das stimmt nicht,  nenne doch deinen Compiler 
ganz einfach, vielleicht kann das dann jemand bestätigen oder 
verneinen...
Aber in meinem Link kannst Du online 3 C Compiler testen mit einem 
Klick! und alle 3 scheitern.
Wenn Du jetzt einen hast der das macht..toll...dann zeigt das ein mal 
mehr ein Problem von C ..das die Compilerwahl je nach Fehler pures Glück 
ist, ob es der richtige ist...
Unter anderen war der ach so hochgelobte gcc dabei und MS Visual C

Bei Pascal gibt es nur den defacto Standard Delphi/Freepascal. Beide 
melden es.

Du wirst doch zugeben müssen das es schon blöd ist, das es pures Glück 
ist, wo was gemeldet wird und so nicht.
Ansonsten gäbe es ja diese Kritik nicht.
Und wenn das jetzt NACHTRÄGLICH in Deiner Oberfläche implementiert 
ist..schön..aber wir reden hiervon üblichen C Compilern nicht von Guis 
oder extra Tools die sich jemand geschrieben hat um solche Fehler zu 
finden..es geht darum was beim Standard gemeldet wird und was nicht


Noch besser, zeig doch mal Deinen kompletten Code, damit man es mal copy 
PAste testen kann oder Dir sagen kann, was bei Deinem Beispiel falsch 
ist

: Bearbeitet durch User
von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

ich habs gerade noch mal so ausprobiert..nun gehts ohne Fehler und ohne 
Fehlermeldung?!
Sowohl im Rextester als auch in Codeblocks?
Was mache ich denn jetzt plötzlich falsch?
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <stdint.h>
4
5
int main()
6
{
7
    uint16_t i = 30000 * 2;
8
    printf("%d",i);
9
    return 0;
10
}

Ergebnis: 60000

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


Lesenswert?

Thomas M. schrieb:
> Was mache ich denn jetzt plötzlich falsch?

Du hast immer noch nicht kapiert, was die Ursache des "Problems" ist.

Der Datentyp "int", der vom Compiler für Berechnungen verwendet wird, 
ist je nach Compiler unterschiedlich groß.

Und wenn Du einen Compiler verwendest, der für 32-Bit-Maschinen gedacht 
ist (wie es ein Compiler für den PC oder auch einen ARM ist), dann ist 
ein "int" ein 32-Bit-Datentyp, und die Berechnung liefert keinen 
Überlauf.

Bei einem Compiler für 16-Bit-Maschinen (oder 8-Bit-Maschinen) aber ist 
"int" ein 16-Bit-Datentyp, und es gibt einen Überlauf.

Das ist elementares C und steht in den ersten Kapiteln jedes 
tauglichen Buches über die Sprache drin, und wird in den ersten Wochen 
der Erstsemestervorlesung gelehrt.

--

Ich fände es schön, wenn Du, bevor Du weiter Dinge kritisierst, die Du 
nicht verstehst, weil Du Dich nicht mit ihnen beschäftigen möchtest, Dir 
vielleicht erst mal das nötige Grundlagenwissen aneignen würdest.

Denn das fehlt Dir. Dafür aber bist Du sehr laut.


Und wenn Du keine Lust hast, Dir Wissen anzueignen, dann halte Dich doch 
bitte einfach aus Diskussionen über das entsprechende Thema herasu. Das 
regt Dich weniger auf, und es stört andere nicht.

Ich beispielsweise habe von Ballett echt gar keine Ahnung, und äußere 
mich dazu nicht. Auch über Fußball wirst Du von mir keine Kommentare 
hören, denn das interessiert mich nicht die Bohne.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

"Rufus Τ. F. (rufus) (Moderator)"
"Du hast immer noch nicht kapiert"
Achte auf Deinen Ton Du Vogel!


es geht nun aber auch unter Rextestert Du....!!
Offensichtlich hast Du es nicht gerafft..entweder vorher oder Du 
erkennst den Fehler im Beispiel jetzt nicht..wie auch immer!

Oder eines meiner Beispiele vorher war falsch, deshalb diskutiert mna, 
was Du offenbar nicht schnallst!

Denn wenn das erste Beispiel von mir schon falsch gewesen wäre, wäre die 
ganze Diskussion für die Katz! Verstehst Du?!


Vielleicht sollte ich Dich mal WIEDER beim Forenbetreiber melden!

: Bearbeitet durch User
von Walter K. (vril1959)


Lesenswert?

Thomas M. schrieb:
> Sowohl im Rextester als auch in Codeblocks?


... Rufus hat eigentlich schon alles geschrieben!

Welche Entwicklungsumgebung Du nun für das Erlernen der Basics
nutzt - ist auch vollkommen egal!

Kompiliere und Linke zuerst mal nativ auf Ebene der Kommandozeile - dann 
bekommst Du ein Gefühl dafür, was eigentlich wie passiert - und bringst 
Verständnisprobleme von Datentypen und Castings nicht mit "CodeBlocks" 
in Verbindung.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

viel blabla..aber keine Erklärung dafür was an den vorherigen Beispielen 
anders war, die ja ebenfalls im Rextester getestet wurden!

Wenn nicht alle nur labern würden sondern codebeispiele zegien würden 
udn alle die mal eben im onlinecompiler testen könnten, wäre der ganze C 
vs Pascal Kleinkrieg vielleicht schon längst friedlich beendet.

Aber hier kommt immer nur Gelaber teilweise mit völlig falschen 
Erklärungen weil der Threat schon so lang geworden ist, das viele gar 
nicht mehr die ganzen Vergleiche udn Beispiele kennen

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Thomas M. schrieb:
> Achte auf Deinen Ton Du Vogel!
>
> es geht nun aber auch unter Rextestert Du....!!

Diese Kombination liest Du Dir bitte nochmal durch.

Thomas M. schrieb:
> Aber hier kommt immer nur Gelaber

Nein. Ich wiederhole es: Du weigerst Dich, Dich mit dem Gesagten 
auseinanderzusetzen.

Das ist bei Dir schon pathologisch.

von Stefan F. (Gast)


Lesenswert?

Thomas M. schrieb:
> Es ist halt ein totaler Krampf
> das ist Fakt.

Ich glaube Dir, dass diese Eigenschaft für Dich sehr ärgerlich ist. Für 
mich ist das lediglich eine Eigenschaft die ich berücksichtigen muss und 
kann.

Ich benutze trotzdem C in meinen Elektronik freiwillig. Ich habe gar 
keine Lust, mich dort mit anderen Programmiersprachen auseinander zu 
setzen, obwohl ich viele andere kennengelernt habe und mir durchaus 
dessen bewusst bin, dass C ein alter hässlicher Opa ist.

Sogar in meinen Hobbyprojekten für Linux/Windows Desktop bevorzuge ich 
C++.

Das liegt nicht daran, dass ich von C am meisten Ahnung hätte. Mein 
beruflich fundiertes KnowHow liegt stattdessen bei Java.

von Thomas M. (Firma: https://img.favpng.com/23/21/3) (thomasmopunkt)


Lesenswert?

2> es geht nun aber auch unter Rextestert Du....!!

Diese Kombination liest Du Dir bitte nochmal durch.2

Ich bin kein Moderator Du Vogel! Meine Aufgabe ist es nicht hier zu 
schlichten und für Ordnung zu sorgen, daher hab ich mich auch nicht 
vorbildlich zu verhalten..mir ist das Forum und dessen Zukunft 
wumpe..aber als Moderator sieht die Sache anders aus..da sollte man 
seine Wortwahl etwas überdenken

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Thomas M. schrieb:
> aber als Moderator sieht die Sache anders aus..da sollte man seine
> Wortwahl etwas überdenken

Ich stehe zu meiner Wortwahl. Wenn Du Dich in diesem Forum beteiligen 
willst, solltest Du dringend an Deiner Wortwahl arbeiten, denn so, wie 
Du hier auftrittst, verärgerst Du nicht nur mich (was nur mäßig relevant 
ist), sondern vor allem auch die anderen Forennutzer.

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Thomas M. schrieb:
> 2> es geht nun aber auch unter Rextestert Du....!!
>
> Diese Kombination liest Du Dir bitte nochmal durch.2
>
> Ich bin kein Moderator Du Vogel!

Du solltest einfach mal Deine Wortwahl überdenken.

> Meine Aufgabe ist es nicht hier zu
> schlichten und für Ordnung zu sorgen, daher hab ich mich auch nicht
> vorbildlich zu verhalten

Dann liegst Du da schlicht falsch. Auch Du solltest hier einen 
vernünftigen Ton anschlagen.

>..mir ist das Forum und dessen Zukunft
> wumpe..aber als Moderator sieht die Sache anders aus..da sollte man
> seine Wortwahl etwas überdenken

Das sollte man immer tun. Und genau darauf weist Rufus Dich hin.

Wenn Du meinst, dass das für Dich nicht gilt, dann bist Du hier schlicht 
falsch.

--

Zum urspünglichen "Problem", das eigentlich keines ist, wurde schon in 
den ersten paar Beiträgen alles gesagt.

Das eigentliche Problem ist, dass viele C eher nebenbei erlernen: man 
programmiert anfangs eher drauflos, modifiziert hier vorhandenen Code, 
nimmt da ein paar Zeilen mit.

Aber fast niemand setzt sich mal hin und liest ein gutes Buch für 
C-Anfänger.

In 99% der Fälle gelingt es den Leuten dann, leidlich C zu verwenden 
aber in dem einen Prozent der Fälle knallt es eben.

Die interne Behandlung von Integern in C ist aber in der Tat 
Grundlagenwissen, das in jedem Kurs/Buch über C vermittelt wird.

: Bearbeitet durch Moderator
von Karl K. (karl2go)


Lesenswert?

Uiuiui, mein Compiler schmeisst gerade einen...

"Fatal error: Thread escalation detected!"

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Thomas M. schrieb:
> Was mache ich denn jetzt plötzlich falsch?

Du compilierst für ein 32-Bit-Target. Da ist 2 x 30000 überhaupt kein 
Problem.

Wenn Du für einen 8-Bit AVR compilierst, dann (und nur dann) ist "int" 
nur 16 Bit breit und die Integer-Promotion schlägt zu.

Hier der Beweis, dass avr-gcc meckert, wenn das Ergbnis nicht in 16 Bit 
reinpasst:
1
#include <stdint.h>
2
3
int
4
main ()
5
{
6
    uint32_t i = 30000 * 2;
7
}
1
avr-gcc  -mmcu=atmega644 -Wall -gdwarf-2 -std=gnu99 -da -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT test.o -MF dep/test.o.d  -c  ../test.c
2
../test.c: In function 'main':
3
../test.c:6:24: warning: integer overflow in expression [-Woverflow]
4
../test.c:6:14: warning: unused variable 'i' [-Wunused-variable]

Und als allerletztes, warum Du keine Warnung ausgegeben bekommst: Du 
hast in diesem Thread sämtliche Hinweise ignoriert, dass man die 
Warnings für den Compiler auch einschalten muss. Natürlich gilt das nur 
für ein Target, auf dem int nur 16 Bit breit ist. Für 32-Bit-Targets 
wirst Du natürlich keine Warnungen erhalten, da es hier korrekt läuft, 
wie Du ja auch schon selbst festgestellt ist.

Und ja: Auch der Hinweis, dass es für einen Unbedarften gar nicht so 
einfach ist, in der Arduino-Entwicklungsuimgebung die Compiler-Warnungen 
einzuschalten, ist hier schon gefallen. Aber es geht durchaus.

: Bearbeitet durch Moderator
von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

@Karl:

Viel zu spät :-)

Eigentlich hätte er schon viel früher "Warning - 'Pascal' and 'C' used 
in same Thread" werfen müssen.

: Bearbeitet durch Moderator
von Einer K. (Gast)


Lesenswert?

Thomas M. schrieb:
> daher hab ich mich auch nicht
> vorbildlich zu verhalten.

Das ist eine Abscheulichkeit.
Widerlich!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Thomas M. schrieb:
> Ich bin kein Moderator Du Vogel! Meine Aufgabe ist es nicht hier zu
> schlichten und für Ordnung zu sorgen, daher hab ich mich auch nicht
> vorbildlich zu verhalten..mir ist das Forum und dessen Zukunft
> wumpe..aber als Moderator sieht die Sache anders aus..da sollte man
> seine Wortwahl etwas überdenken

Ziemlich einseitige Sicht:

Du äußerst Dich gegenüber Deinen Mitlesern respektlos ("Vogel" und 
ähnliches), erwartest aber vom Gegenüber Höflichkeit. Dein Posting 
lassen wir mal schön stehen, da es genau das richtige Licht auf Dich 
wirft.

von Karl K. (karl2go)


Lesenswert?

Chris D. schrieb:
> Eigentlich hätte er schon viel früher "Warning - 'Pascal' and 'C' used
> in same Thread" werfen müssen.

Ups, hatte ich abgeschaltet.

Frank M. schrieb:
> Wenn Du für einen 8-Bit AVR compilierst, dann (und nur dann) ist "int"
> nur 16 Bit breit und die Integer-Promotion schlägt zu.

Zugegeben ist das aber schon ein bescheuertes Verhalten, dass der 
Compiler das so "starrköpfig" auch für Konstanten umsetzt.

Das hat mich am Anfang irritiert, als ich von ASM kommend in C 
eingestiegen bin. Sowas wie

.EQU Cvshdn = 16*1024*33/(330+33)/5 ;Schwelle Versorgung low (V bei 
330k/33k, 10bit, 5Vref)

geht im AVR Assembler problemlos (innerhalb der Rundungsgrenzen), 
während es mit #define im AVR GCC falsche Werte liefert, obwohl der 
eigentliche Wert wieder in 16bit signed passt.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl K. schrieb:
> Zugegeben ist das aber schon ein bescheuertes Verhalten, dass der
> Compiler das so "starrköpfig" auch für Konstanten umsetzt.

Er muss da so starrköpfig sein. Egal, ob der Compiler es zur 
Compilier-Zeit selbst ausrechnen kann oder das Target es at-runtime 
ausrechnen muss: Es muss dasselbe rauskommen!

Sonst kann man sich auf gar nichts mehr verlassen - je nach 
Optimierungsstufe muss man sich sonst jedesmal fragen: "Rechnet das 
jetzt der Compiler oder der AVR?!?"

Ich hatte das Argument bereits hier angeführt:

Beitrag "Re: [C] Böse Falle: Datentyp korrekt angegeben, falscher verwendet"

Es gab nur keine Reaktion darauf. Vielleicht muss ich es auch etwas 
schärfer formulieren:

 Code 1:
1
    uint32_t i = 30000 * 2;

Code 2:
1
    int a = 30000;
2
    int b = 2;
3
    uint32_t i = a * b;

Code 3:
1
    int a = rand();     // liefert at runtime 30000
2
    int b = rand();     // liefert at runtime 2
3
    uint32_t i = a * b;

Es muss in allen 3 Fällen dasselbe Ergebnis rauskommen. Das kann man nur 
gewährleisten, wenn sich der Compiler "starrköpfig" wie das das Target 
(hier: AVR) selbst verhält.

Von daher ist auch W.S' Forderung, der Compiler solle doch intern mit 
256 Bit rechnen, Unsinn. Denn der Compiler muss genau so rechnen wie das 
Target, sonst kämen - je nach Optimierungsstufe - unterschiedliche 
Ergebnisse raus.

von Karl K. (karl2go)


Lesenswert?

Frank M. schrieb:
> Code 1:    uint32_t i = 30000 * 2;
>
> Code 2:    int a = 30000;
>     int b = 2;
>     uint32_t i = a * b;

Nee, das Beispiel ist ja Quatsch. Bei Code 2 gibst Du explizit einen 
Datentyp vor:

> Code 1:    uint32_t i = 30000 * 2;
>
> Code 2:    long a = 30000;
>     long b = 2;
>     uint32_t i = a * b;

Und schon kommen unterschiedliche Ergebnisse auf dem AVR. Und am PC 
hängt es davon ab, ob Windows (int=32, long=32) oder Linux (int=32, 
long=64), sobald die Zahlen größer werden.

Sorry, die Idee dahinter ist schon klar, aber trotzdem klingt das nach 
fauler Ausrede, weil man es halt mal so implementiert hat.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl K. schrieb:
> Bei Code 2 gibst Du explizit einen Datentyp vor:

Ja, natürlich "int", denn 30000 ist ein int und 2 ist ein "int".

> Code 1: uint32_t i = 30000 * 2;
> Code 2: long a = 30000;

Falsche Transferleistung Deinerseits:

Wenn Du Code2 in "long a" abänderst, dann musst Du auch in in Code 1 
"30000L" schreiben. Und schon kommt wieder dasselbe raus.

von (prx) A. K. (prx)


Lesenswert?

Karl K. schrieb:
> Zugegeben ist das aber schon ein bescheuertes Verhalten, dass der
> Compiler das so "starrköpfig" auch für Konstanten umsetzt.

Entweder rechnet er überall innerhalb des gegebenen Datentyps.
Oder er rechnet überall entsprechend der Breite des Ergebnisses.
Aber nicht je nach Laune und grad der Erkenntnis mal so mal so.

Es wäre doch etwas peinlich, wenn ein völlig korrekt arbeitender 
Compiler bei voller Kenntnis aller Quellen und entsprechender 
Optimierung zu Konstanten anders rechnet, als wenn man jede Quelle 
einzeln mit ohne oder mit schwacher Optimierung rechnet.

Man kann Rechnungen natürlich auch anders definieren, wenn man eine neue 
Sprache erfindet. Indem das Ergebnis einer Addition ein Bit mehr 
benötigt als der breitere Operand, und das Ergebnis einer Multiplikation 
die doppelte Anzahl. Nur sollte man dann in sämtlichen Berechnungen mit 
kleinerem Speicher als Ergebnis explizite Downcasts mit entsprechend 
definiertem Modulo- oder Sättigungsverhalten einbauen, oder Exceptions 
werfen lassen.

Noch sinnvoller - und weitaus besser prüfbar - wird es, wenn man dann 
sämtliche Variablen mit expliziter Wertebereichsangabe versieht, statt 
mit Datentypen fixer von der Plattform definierter Breite. Ok, das wird 
etwas bremsen, aber wenn schon richtig, dann wirklich richtig.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> und das Ergebnis einer Multiplikation die doppelte Anzahl.

Das hiesse dann bei AVR, dass dieser eine 16-Bit-Multiplikation 
grundsätzlich in 32-Bit rechnen müsse.

Da sinkt die Verarbeitungszeit aber dramatisch und jeder würde sich die 
Augen reiben: "Warum ist der denn so arschlangsam?!?". Aus diesem Grund 
ist es auch sinnvoll, dass der Programmierer durch Casts der Operanden 
bestimmt, wie die Target-Plattform (oder auch der Compiler) den Ausdruck 
zu berechnen hat.

: Bearbeitet durch Moderator
von (prx) A. K. (prx)


Lesenswert?

Frank M. schrieb:
> Das hiesse dann bei AVR, dass dieser eine 16-Bit-Multiplikation
> grundsätzlich in 32-Bit rechnen müsse.

Er müsste die volle 16x16=>32 Bit Multiplikation rechnen. Also 4 
Teilprodukte statt 3. Oft würde aber der Folgecode das wieder 
reduzieren, so dass der Compiler daraus eine sparsamere Multiplikation 
ableiten kann.

Wie gesagt: Wenn man es bei solchen Überlegungen nur halb richtig macht, 
indem man den faulen Kompromiss einfach nur ein paar Zentimeter 
verschiebt, ändert man nicht wirklich etwas am grundsätzlichen Problem.

Oder man orientiert sich an dem, was gut implementierbar ist, und 
jammert dann darüber, dass man wissen muss, was man tut, ohne es 
explizit im Code zu erblicken.

: Bearbeitet durch User
von Karl K. (karl2go)


Lesenswert?

Frank M. schrieb:
> Ja, natürlich "int", denn 30000 ist ein int und 2 ist ein "int".

Nicht natürlich. Dein int passt hier "zufällig" weil Du es so gewählt 
hast zum int, mit dem der Compiler die Konstanten berechnet.

von (prx) A. K. (prx)


Lesenswert?

Karl K. schrieb:
> Nicht natürlich. Dein int passt hier "zufällig" weil Du es so gewählt
> hast zum int, mit dem der Compiler die Konstanten berechnet.

30000 ist nicht zufällig "int", sondern immer.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl K. schrieb:
> Nicht natürlich. Dein int passt hier "zufällig" weil Du es so gewählt
> hast zum int, mit dem der Compiler die Konstanten berechnet.

Eine numerische Konstante ist per definitionem ein "int". Wenn Du eine 
long-Kontante haben möchtest, musst Du ein L an die Zahlenkonstante 
anhängen. Das sind Basics!

Du kannst nicht vom Compiler verlangen, dass er Zahlenkonstanten so 
behandelt, wie es Dir gerade in den Kram passt.

: Bearbeitet durch Moderator
von Stefan F. (Gast)


Lesenswert?

Frank M. schrieb:
> Er muss da so starrköpfig sein. Egal, ob der Compiler es zur
> Compilier-Zeit selbst ausrechnen kann oder das Target es at-runtime
> ausrechnen muss: Es muss dasselbe rauskommen!
>
> Sonst kann man sich auf gar nichts mehr verlassen - je nach
> Optimierungsstufe muss man sich sonst jedesmal fragen: "Rechnet das
> jetzt der Compiler oder der AVR?!?"

Das ist ein sehr einleuchtendes Argument - finde ich.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Man betrachte das folgende C-Beispiel (AVR-GCC)

1
#include <stdio.h>
2
#include <inttypes.h>
3
4
int16_t  i1, i2;
5
uint32_t u1, u2;
6
7
void init(void) {
8
  i1 = 20000;
9
  i2 = 3;
10
}
11
12
int main(void) {
13
  init();
14
  u1 = i1 * i2;
15
  u2 = 20000 * 3;
16
  printf("%"PRIu32"\n", u1);
17
  printf("%"PRIu32"\n", u2);
18
}

und den 1:1 nach Pascal (AVR-FPC) übersetzten Code:

1
program test;
2
3
var i1, i2: int16;
4
var u1, u2: uint32;
5
6
procedure init;
7
begin
8
  i1 := 20000;
9
  i2 := 3;
10
end;
11
12
begin
13
  init;
14
  u1 := i1 * i2;
15
  u2 := 20000 * 3;
16
  writeln(u1);
17
  writeln(u2)
18
end.

Anmerkung: Damit die Ausgabefunktionen printf und writeln auf dem AVR
funktionieren, muss ggf. das I/O-System geeignet initialisiert werden,
was jetzt aber vom eigentlichen Problem zu sehr ablenken würde.

Würden alle vorkommenden Multiplikationen mathematisch korrekt
ausgeführt werden, würden beide Programme

1
60000
2
60000

ausgeben.

Tatsächlich gibt aber das C-Programm

1
4294961760
2
4294961760


und das Pascal-Programm
1
4294961760
2
60000

aus.

In C sind beide Ergebnisse auf Grund des beschränkten int-Wertebereichs
aus mathematischer Sicht falsch, aber sie sind in beiden Fällen gleich
falsch.

In Pascal ist (aus demselben Grund wie in C) das erste Ergebnis
mathematisch falsch, das zweite hingegen (weil in Pascal Konstanten
auf spezielle Weise behandelt werden) korrekt.

Ein Pascal-Fan könnte jetzt argumentieren, dass in C 100% der Ergebnisse
mathematisch falsch sind, während es in Pascal nur 50% sind.

Ein C-Fan hingegen würde argumentieren, dass die Ergebnisse zwar
mathematisch falsch, aber wenigstens konsequent falsch sind, während in
Pascal das Ergebnis der Multiplikation davon abhängt, ob die Operanden
als Konstanten oder Variablen gegeben sind.

Wer von beiden recht hat, darüber darf sich jeder sein eigenes Urteil
bilden.

Meine persönliche Meinung dazu:

Die Regeln für die implizite Typkonvertierung bei Integer-Operationen
sind in beiden Sprachen¹ im Vergleich zu anderen Sprachen relativ
kompliziert und schwer zu merken. In Pascal kommt noch aber eine weitere
Regel für die Sonderbehandlung von Konstanten hinzu, was die Sache noch
komplizierter macht. Diese Zusatzregel mag in gewissen Situationen ihre
Vorteile haben, dennoch bevorzuge ich hier das konsequentere Vorgehen
von C. Es gibt auch Bereiche, wo Pascal seine Vorzüge hat, aber dieser
hier gehört meiner Meinung nach definitiv nicht dazu.

———————————————
¹) So verzichtet bspw. Haskell komplett auf implizite
   Typkonvertierungen, weswegen dafür auch kein Regelwerk
   erforderlich ist.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> In Pascal kommt noch aber eine weitere
> Regel für die Sonderbehandlung von Konstanten hinzu, was die Sache noch
> komplizierter macht. Diese Zusatzregel mag in gewissen Situationen ihre
> Vorteile haben, dennoch bevorzuge ich hier das konsequentere Vorgehen
> von C. Es gibt auch Bereiche, wo Pascal seine Vorzüge hat, aber dieser
> hier gehört meiner Meinung nach definitiv nicht dazu.

Absolute Zustimmung.

Nur mit einem konsequentem Rechenweg wird ein Ergebnis unabhängig von 
der Optmierungsstufe (Compiler rechnet vs. Target rechnet) 
reproduzierbar. Daher ist die Pascal'sche Sonderbehandlung von 
Konstanten inkonsequent und macht das ganze unnötig komplizierter.

: Bearbeitet durch Moderator
von (prx) A. K. (prx)


Lesenswert?

Frank M. schrieb:
> Eine numerische Konstante ist per definitionem ein "int".

Wenn eine dezimale Konstante nicht in den Wertebereich von "int" passt, 
wird sie automatisch erst "long", dann "long long" (wenn vorhanden).

Bei Konstanten auf anderer Basis kommen auch noch vorzeichenlose Typen 
in Frage. Bei 16-Bit "int" ist 32768 also implizit "long", 0x8000 aber 
implizit "unsigned". Erst 0x10000 ist "long".

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Wenn eine dezimale Konstante nicht in den Wertebereich von "int" passt,
> wird sie automatisch erst "long", dann "long long" (wenn vorhanden).

Ja, sorry, natürlich. Ich wollte jetzt nicht die ganzen 
Sonderbehandlungen (Zahlen ab 32768 und HEX-Schreibweise) auspacken, die 
dann noch mehr verwirren.

Hier ging es um die magische 30000 des TO, die ist - egal wie man es 
dreht und wendet - so oder so "int".

Von daher ist Deine Formulierung

> 30000 ist nicht zufällig "int", sondern immer.

natürlich präziser.

Jetzt fehlen nur noch Oktal- und Binärschreibweisen. Ab wann werden 
diese zu "long"? Welche sind dabei implizit unsigned? ;-)

: Bearbeitet durch Moderator
von Bernd K. (prof7bit)


Lesenswert?

Karl K. schrieb:
> Zugegeben ist das aber schon ein bescheuertes Verhalten, dass der
> Compiler das so "starrköpfig"

Wo kämen wir hin wenn der Compiler sich nicht starrköpfig an seine 
eigenen Regeln halten würde? Künstliche Impertinenz?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Frank M. schrieb:
> Nur mit einem konsequentem Rechenweg wird ein Ergebnis unabhängig von
> der Optmierungsstufe (Compiler rechnet vs. Target rechnet)
> reproduzierbar. Daher ist die Pascal'sche Sonderbehandlung von
> Konstanten inkonsequent und macht das ganze unnötig komplizierter.

Konsequent und unabhängig von der Optmierungsstufe ist der Rechenweg
auch in Pascal. Es geht bei der Entscheidung, ob ein Ausdruck
mathematisch korrekt oder modulo 2^n berechnet wird, nicht darum, was
der Compiler zur Compilezeit berechnen kann, sondern was im Sinne der
Sprachdefinition als konstanter Ausdruck definiert ist. Danach sind
konstante Ausdrücke

- Literale
- in /const/-Abschnitten definierte Sysmbole
- Verknüpfungen konstanter Ausdrücke mittels der Standardoperatoren

Nur diese werden mathematisch korrekt berechnet, alles andere unterliegt
den Regeln der implizitem Typkonvertierung und wird – wie auch in C –
modulo 2^n ausgewertet.

In folgendem Beispiel

1
program test;
2
3
var i1, i2: int16;
4
var u1, u2: uint32;
5
6
begin
7
  i1 := 20000;
8
  i2 := 3;
9
  u1 := i1 * i2;
10
  writeln(u1);
11
end.

berechnet der Compiler das Produkt zwar zur Compilezeit, trotzdem ist
das Ergebnis nicht 60000, sondern 4294961760, weil im Ausdruck i1*i2 die
Operanden keine Konstanten, sondern Variablen (mit zur Compilezeit
bekanntem Wert) sind.

Insofern ist das Ergebnis auch in Pascal klar definiert. Pascal verfolgt
bei der Auswertung von Ausdrücken nur eine etwas andere Philosophie als
C, die man mögen kann oder auch nicht.

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Konsequent und unabhängig von der Optmierungsstufe ist der Rechenweg
> auch in Pascal.

Das hatte ich auch schon so verstanden. Mit "inkonsequent" meinte ich 
die "magische" Sonderregel bzgl. der Behandlung von Konstanten. Warum 
muss das sein?

Ein Optimierer könnte bei C so vorgehen:

Schritt 1: Original-Source:
1
   int a = 30000;
2
   int b = 2;
3
   uint32t_ i = a * b;

Schritt 2: Wegoptimieren der Variablen & Zusammenfassen der Konstanten:
1
   uint32t_ i = 30000 * 2;

Schritt 3: Berechnung des Produktes im int-Zahlenbereich des Targets.

Hier sind die Optimierungsschritte transparent und auch für einen 
unbedarften Leser verständlich. Hier führen die obigen Schreibweisen zu 
demselben Ergebnis.

Ein Pascal-Optimierer darf den Schritt von 1 nach 2 jedoch nicht 
vollziehen, denn beide Schreibweisen führen in Pascal zu 
unterschiedlichen Ergebnissen, wie Du oben auch schön demonstriert hast. 
Hier muss ein Pascal-Optimierer wegen der Sonderbehandlung von 
Konstanten einen Schlenker einbauen.

Dass beide Schreibweisen oben in Pascal nicht äquivalent sind, weiß 
bestimmt auch nicht jeder Pascal-Programmierer. Dies könnte für ihn 
ebenso zur "bösen Falle" werden - um wieder zum Thread-Titel zu kommen 
;-)

: Bearbeitet durch Moderator
von Stefan F. (Gast)


Lesenswert?

Yalu X. schrieb:
> Literale...werden mathematisch korrekt berechnet

Sicher hat auch das irgendwo seine Grenzen. Auch Pascal kann nicht 
beliebig grosse Zahlen berechnen.

von (prx) A. K. (prx)


Lesenswert?

Und dann hätten wir noch den C Präprozessor, der zwar selten rechnet, 
dann aber nicht unbedingt streng nach den gleichen Regeln wie C.

: Bearbeitet durch User
von Uhu U. (uhu)


Lesenswert?

Auf dem 8-Bitter funktioniert diese Variante:
1
unsigned i = 30000u * 2;

Für unsere C-Basher dürfte das aber zu sperrig sein, als dass es auf 
Dauer in deren Hirn-Biotop überleben könnte…

: Bearbeitet durch User
Beitrag #5767273 wurde vom Autor gelöscht.
von Uhu U. (uhu)


Lesenswert?

A. K. schrieb:
> Und dann hätten wir noch den C Präprozessor, der zwar selten rechnet,
> dann aber nicht unbedingt streng nach den gleichen Regeln wie C.

Mir ist noch kein derartiger Fall untergekommen - das Ergebnis war stets 
nur ein Ausdruck, den der Compiler dann berechnet hat, sofern das zur 
Compilezeit möglich ist.

Hast du ein Beispiel, wann der cpp rechnet?

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Uhu U. schrieb:
> Hast du ein Beispiel, wann der cpp rechnet?

Beim Auswerten der Bedingung für ein #if kann man ihn zum Rechnen 
zwingen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Stefanus F. schrieb:
> Yalu X. schrieb:
>> Literale...werden mathematisch korrekt berechnet
>
> Sicher hat auch das irgendwo seine Grenzen. Auch Pascal kann nicht
> beliebig grosse Zahlen berechnen.

Sicher. Die Berechnungen scheinen in 64-bit-signed ausgeführt zu werden.
±2**63 ist aber für AVR-Verhältnisse praktisch unendlich ;-)

von Uhu U. (uhu)


Lesenswert?

Bernd K. schrieb:
> Beim Auswerten der Bedingung für ein #if kann man ihn zum Rechnen
> zwingen.

OK, da muss er, weil er das #if auswerten muss. Aber im C-Text rechnet 
er, soviel ich weiß, nie.

von Uhu U. (uhu)


Lesenswert?

Yalu X. schrieb:
> ±2**63 ist aber für AVR-Verhältnisse praktisch unendlich ;-)

Nein, ist es nicht. Der avr-gcc kennt den Datentyp long long - der ist 
64 Bit lang.

von Karl K. (karl2go)


Lesenswert?

Yalu X. schrieb:
> In Pascal ist (aus demselben Grund wie in C) das erste Ergebnis
> mathematisch falsch, das zweite hingegen (weil in Pascal Konstanten
> auf spezielle Weise behandelt werden) korrekt.

Dass der Compiler aber im ersten Fall eine Warnung gibt, ist Dir schon 
aufgefallen?

Womit wir wieder bei "Klar, wenn wir Warnungen ignorieren, können wir 
sonstwas >beweisen<" wären.

von Karl K. (karl2go)


Lesenswert?

Uhu U. schrieb:
> Auf dem 8-Bitter funktioniert diese Variante:

Guten Morgen, auch schon aufgewacht.

Nur ist es erstmal unersichtlich, warum eine Zahl 30000 als unsigned 
oder long angegeben werden soll, passt sie doch wunderbar in int.

von Uhu U. (uhu)


Lesenswert?

Karl K. schrieb:
> Nur ist es erstmal unersichtlich, warum eine Zahl 30000 als unsigned
> oder long angegeben werden soll, passt sie doch wunderbar in int.

Intelligenz ist, wenn man weiter denkt…

von Karl K. (karl2go)


Lesenswert?

Yalu X. schrieb:
> berechnet der Compiler das Produkt zwar zur Compilezeit, trotzdem ist
> das Ergebnis nicht 60000, sondern 4294961760

int01.lpr(17,12) Warning: Range check error while evaluating constants 
(-5536 must be between 0 and 4294967295)

Und wie groß soll der Compiler die Warnung noch schreiben, damit Du 
siehst, dass da was nicht stimmt.

Frank M. schrieb:
> Ein Pascal-Optimierer darf den Schritt von 1 nach 2 jedoch nicht
> vollziehen, denn beide Schreibweisen führen in Pascal zu
> unterschiedlichen Ergebnissen, wie Du oben auch schön demonstriert hast.

Natürlich darf er das und er tut das auch, ist ja nicht blöd. Und dann 
gibts eine Warnung, siehe oben.

von Karl K. (karl2go)


Lesenswert?

Uhu U. schrieb:
> Intelligenz ist, wenn man weiter denkt…

Dann mach mal, an einem Beispiel wo es nicht so offensichtlich ist:

.EQU Cvshdn = 16*1024*33/(330+33)/5 ;Schwelle Versorgung low (V bei
330k/33k, 10bit, 5Vref)

Funktioniert so im AVR Assembler. Jetzt bitte in C.

von Stefan F. (Gast)


Lesenswert?

Karl K. schrieb:
> .EQU Cvshdn = 16*1024*33/(330+33)/5 ;Schwelle Versorgung low (V bei
> 330k/33k, 10bit, 5Vref)
>
> Funktioniert so im AVR Assembler. Jetzt bitte in C.

Da sehe ich schon auf den ersten Blick, dass 16*1024*33 nicht in einen 
16bit Integer passt.

von Rolf M. (rmagnus)


Lesenswert?

Frank M. schrieb:
> A. K. schrieb:
>> und das Ergebnis einer Multiplikation die doppelte Anzahl.
>
> Das hiesse dann bei AVR, dass dieser eine 16-Bit-Multiplikation
> grundsätzlich in 32-Bit rechnen müsse. Da sinkt die Verarbeitungszeit
> aber dramatisch und jeder würde sich die Augen reiben: "Warum ist der
> denn so arschlangsam?!?".

Tatsächlich sind bei den Architekturen, die ich kenne, die 
Multiplikationsergebnisse auf Assembler-Ebene doppelt so groß wie die 
Operanden (auch beim AVR hat mul für jeden Operanden ein Register, 
während das Ergebnis in einem Registerpaar gespeichert wird, siehe 
https://www.microchip.com/webdoc/avrassembler/avrassembler.wb_MUL.html 
). Und dann bekommt man dadurch erst das von dir angesprochene Problem: 
Ich will zwei Werte multiplizieren, das Ergebnis könnte je nach den 
Werten doppelt so groß sein, aber der Compiler verwirft die obere 
Hälfte, da der Ergebnistyp der selbe sein muss wie die Operanden. Ich 
muss also auf Quellcode-Ebene die Operanden erst auf die doppelte Größe 
hochcasten, damit dann die Multiplikation in doppelter Breite 
durchgeführt werden und der Complier dann gefahrlos die obere Hälfte des 
Ergebnisses wegwerfen kann.

Thomas M. schrieb:
> HAst Du meine Links/Codebeispiele eigentlich gesehen?!?
> In 3 verschiedenen C Compilern passiert absolut nichts!

Ich hab mal durchgeschaut. Ich finde keine Links auf deine 3 
verschiedenen C-Compiler, mit denen es nicht funktioniert haben soll. 
Aber vielleicht hab ich es übersehen? Der Thread ist ja schon etwas 
länger.

> Anstatt nur rumzuposaunen das stimmt nicht,  nenne doch deinen Compiler
> ganz einfach, vielleicht kann das dann jemand bestätigen oder
> verneinen...

GCC. Hier ein Link: https://godbolt.org/z/nBWvif

> Aber in meinem Link kannst Du online 3 C Compiler testen mit einem
> Klick! und alle 3 scheitern.

Ich finde nur deinen Pascal-Compiler-Link, wo man auch C-Compiler 
auswählen kann, aber nur für PC, wo sich das Problem nicht ergibt.

> Wenn Du jetzt einen hast der das macht..toll...dann zeigt das ein mal
> mehr ein Problem von C ..das die Compilerwahl je nach Fehler pures Glück
> ist, ob es der richtige ist...

Und das ist in deinem heiß geliebten Pascal anders?

> Unter anderen war der ach so hochgelobte gcc dabei und MS Visual C
>
> Bei Pascal gibt es nur den defacto Standard Delphi/Freepascal. Beide
> melden es.

Aha, also ist Pascal eine bessere Sprache, weil es nur zwei Compiler 
gibt?

von Carl D. (jcw2)


Lesenswert?

Karl K. schrieb:
> Uhu U. schrieb:
>> Auf dem 8-Bitter funktioniert diese Variante:
>
> Guten Morgen, auch schon aufgewacht.
>
> Nur ist es erstmal unersichtlich, warum eine Zahl 30000 als unsigned
> oder long angegeben werden soll, passt sie doch wunderbar in int.

Es ist erst mal unersichtlich, warum bei einer Division angegeben werden 
muß, daß gerne eine Interger-Division haben will, obwohl beide Operanden 
und das Ergebnis vom Typ integer sind.

Wenn man will, findet man in jeder Sprache ein Haar. Und obiges ist nur 
eins von vielen. Welche Haarsammlung die beliebtere ist, kann man an 
vielen Kenngrößen ablesen. Wenn man will.

von Karl K. (karl2go)


Lesenswert?

Stefanus F. schrieb:
> Da sehe ich schon auf den ersten Blick, dass 16*1024*33 nicht in einen
> 16bit Integer passt.

Hallo? Beispiel für C? Überfordert?

von Stefan F. (Gast)


Lesenswert?

Karl K. schrieb:
> Hallo? Beispiel für C? Überfordert?

Die Frage ist mir echt zu kindisch.
1
#include <stdio.h>
2
#include <stdint.h>
3
4
#define Cvshdn 16UL*1024*33/(330+33)/5
5
6
int main()
7
{
8
    printf("Cvshdn=%li\n",Cvshdn);
9
    return 0;
10
}

Was ist daran jetzt so kompliziert?

von Karl K. (karl2go)


Lesenswert?

Stefanus F. schrieb:
> Was ist daran jetzt so kompliziert?

Na nix, aber sieht schon komisch aus.

#define Cvshdn 16*1024UL*33/(330+33)/5

sollte aber auch gehen.

von Stefan F. (Gast)


Lesenswert?

Karl K. schrieb:
> Na nix, aber sieht schon komisch aus.

Ich bin ganz sicher nicht in in einer C Blase groß geworden. Aber für 
mich ist vollkommen klar, dass einer der ersten beiden Operanden als UL 
gekennzeichnet werden muss, damit die ganze Chose mit einem Long-Integer 
Algorithmus berechnet wird.

Wenn ich ein Ergebnis als Fließkommazahl erwarte, muss ich das ja auch 
ausdrücklich hinschreiben.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Karl K. schrieb:
> Yalu X. schrieb:
>> In Pascal ist (aus demselben Grund wie in C) das erste Ergebnis
>> mathematisch falsch, das zweite hingegen (weil in Pascal Konstanten
>> auf spezielle Weise behandelt werden) korrekt.
>
> Dass der Compiler aber im ersten Fall eine Warnung gibt, ist Dir schon
> aufgefallen?

Nein, ist mir nicht. Der FPC 3.3.1 gibt nur folgende Warnungen aus:
1
pastest.pas(14,9) Warning: Variable "i1" does not seem to be initialized
2
pastest.pas(14,14) Warning: Variable "i2" does not seem to be initialized

Der GCC 8.2.0:

1
ctest.c: In function 'main':
2
ctest.c:15:14: warning: integer overflow in expression of type 'int' results in '-5536' [-Woverflow]
3
   u2 = 20000 * 3;

Den Überlauf in Zeile 14 sieht keiner der beiden Compiler, da die
Initialisierung von i1 und i2 in einem Unterprgramm erfolgt. Die gleiche
Warnung erscheint übrigens auch für den Code des TE, und das sogar ohne
explizite -Wxxx-Option.

> Womit wir wieder bei "Klar, wenn wir Warnungen ignorieren, können wir
> sonstwas >beweisen<" wären.

So ist es. Man sollte die Warnungen des C-Compilers durchaus ernst
nehmen, dann vermeidet man viele unliebsame Überraschungen :)


Karl K. schrieb:
> Yalu X. schrieb:
>> berechnet der Compiler das Produkt zwar zur Compilezeit, trotzdem ist
>> das Ergebnis nicht 60000, sondern 4294961760
>
> int01.lpr(17,12) Warning: Range check error while evaluating constants
> (-5536 must be between 0 and 4294967295)
>
> Und wie groß soll der Compiler die Warnung noch schreiben, damit Du
> siehst, dass da was nicht stimmt.

Wieso greifst du mich jetzt an? Hat dich dein Kreuzzug gegen C schon so
verblendet, dass du nicht bemerkt hast, dass ich mit diesem Beispiel
dein geliebtes Pascal gegen ungerechtfertigte Kritik verteidigt habe?

Ich habe Frank oben (irrtümlicherweise) so verstanden, dass das Ergebnis
von Integer-Operationen möglicherweise von der Optimierungsstufe des
Compilers abhängt (d.h. davon, ob er ein Ausdruck zur Compilezeit
berechnet oder nicht). Wenn dem so wäre, wäre das Ergebnis in dem
Beispiel wegen der Compilezeitberechnung des Produkts 60000, während es
in meinem Beispiel weiter oben (wo die Berechnung zur Laufzeit
stattfindet) 4294961760 ist. Damit wäre das Verhalten des Compilers
unvorhersehbar, was ein klares Argument gegen Pascal wäre.

Tatsächlich ist das Ergebnis aber in beiden Fällen 4294961760 und
damit unabhängig von der Optimierungsstufe, wodurch die Ehre von Pascal
bzw. dessen Compiler FPC – zumindest, was diesen Aspekt betrifft –
wiederhergestellt ist.

Und dafür, dass ich dies aufgezeigt habe, bellst du mich nun an :-/

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Ich habe Frank oben (irrtümlicherweise) so verstanden, dass das Ergebnis
> von Integer-Operationen möglicherweise von der Optimierungsstufe des
> Compilers abhängt (d.h. davon, ob er ein Ausdruck zur Compilezeit
> berechnet oder nicht).

Gut, dass Du das richtigstellst. Selbstverständlich habe ich oben 
gefordert, dass unabhängig von der Optimierungsstufe immer dasselbe 
Ergebnis rauskommen muss. Daraus lässt sich dann folgern, dass der 
C-Compiler gar nicht anders kann, als immer im Wertebereich des 
Target-Systems zu rechnen.

q.e.d

von Uhu U. (uhu)


Lesenswert?

Karl K. schrieb:
> .EQU Cvshdn = 16*1024*33/(330+33)/5 ;Schwelle Versorgung low (V bei
> 330k/33k, 10bit, 5Vref)
>
> Funktioniert so im AVR Assembler. Jetzt bitte in C.

Man sieht doch auf den ersten Blick, dass 1024*33 größer als 32767 ist - 
der integer overflow ist also sicher und deswegen sorgt man gleich 
dafür, dass der Ausdruck im long format berechnet wird.

Wenn es nicht so augenscheinlich ist, rechnet man entweder nach oder 
bohrt auf Verdacht auf long auf - kostet ja nichts und gibt sogar eine 
Warnung, falls das Ergebnis für die Zielvariable zu groß ist.

Wie es immer ist: man muss die Regeln kennen und beachten, wenn man 
nicht verunglücken will.

von Karl K. (karl2go)


Lesenswert?

Yalu X. schrieb:
> dein geliebtes Pascal

Der zweite Moderator, der hier Programmiersprachen personalisiert?

Yalu X. schrieb:
> Tatsächlich ist das Ergebnis aber in beiden Fällen 4294961760 und
> damit unabhängig von der Optimierungsstufe

Was aber nur daran liegt, dass Du im ersten Beispiel zu einem Trick 
greifst und die Konstantenzuweisung in eine Subroutine auslagerst. 
Machst Du das im Hauptprogramm, erkennt der Compiler, dass es Konstanten 
sind, verrechnet diese miteinander und gibt eine Warnung wegen 
Bereichsüberschreitung.

Es ist völlig egal, wie falsch der Compiler hier rechnet. Er gibt eine 
Warnung aus, und damit ist klar, hier muss was geändert werden. In dem 
Fall ist das ein einfaches und überschaubares Beispiel. Du kannst ja mal 
spasseshalber die Druckberechnung für einen BME280 für AVR optimieren.

Und es ist auch illusorisch zu sagen, durch das Verhalten des 
C-Compilers wird es portierbar. Unter Windows ist int 32 Bit, unter AVR 
16 Bit. Damit funktioniert die Druckberechnung beim Test unter Windows, 
übertragen auf den AVR aber nicht mehr. BTDT.

von Uhu U. (uhu)


Lesenswert?

Karl K. schrieb:
> Und es ist auch illusorisch zu sagen, durch das Verhalten des
> C-Compilers wird es portierbar.

Es lässt sich aber leicht machen: man definiert sich abhängig von der 
vordefinierten Kontanten INT_MAX den passenden Datentyp.

INT_MAX ist in limits.h definiert.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl K. schrieb:
> Der zweite Moderator, der hier Programmiersprachen personalisiert?

Lass doch mal den Moderator da raus. Auch wir als Moderatoren möchten 
wie jeder andere auch als normale User am Forum teilnehmen. Wenn wir als 
Moderator fungieren, dann teilen wir das schon mit.

Keinesfalls kannst Du uns eine persönliche Meinung zu einem Thema 
absprechen. Du kannst Dir gewiss sein, dass wir das gut auseinander 
halten können.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl K. schrieb:
> Und es ist auch illusorisch zu sagen, durch das Verhalten des
> C-Compilers wird es portierbar.

Wenn man sich anschaut, auf wie viele unterschiedliche Plattformen Linux 
portiert wurde (mehrer Dutzende), würde ich sagen: Die Tatsachen 
sprechen gegen Dich. Und Linux (von den ganzen anderen Unix-Derivaten 
spreche ich noch nichtmals) ist nicht das einzige Betriebssystem, was in 
C geschrieben wurde. Von wegen Illusion.

Wie viele Betriebssysteme würden dagegen in Pascal geschrieben? Ich 
kenne keins. Ganz entfernt könnte einem noch Oberon in den Kopf 
schiessen. Aber das ist eine ganz andere Liga.

von Uhu U. (uhu)


Lesenswert?

Frank M. schrieb:
> Wie viele Betriebssysteme würden dagegen in Pascal geschrieben? Ich
> kenne keins.

Mindestens eins: Solo.

The Solo Operating System: A Concurrent Pascal Program
https://www.researchgate.net/publication/220281517_The_Solo_Operating_System_A_Concurrent_Pascal_Program

von Yalu X. (yalu) (Moderator)


Lesenswert?

Karl K. schrieb:
> Yalu X. schrieb:
>> Tatsächlich ist das Ergebnis aber in beiden Fällen 4294961760 und
>> damit unabhängig von der Optimierungsstufe
>
> Was aber nur daran liegt, dass Du im ersten Beispiel zu einem Trick
> greifst und die Konstantenzuweisung in eine Subroutine auslagerst.
> Machst Du das im Hauptprogramm, erkennt der Compiler, dass es Konstanten
> sind, verrechnet diese miteinander und gibt eine Warnung wegen
> Bereichsüberschreitung.

Genau ist es auch in C.

> Und es ist auch illusorisch zu sagen, durch das Verhalten des
> C-Compilers wird es portierbar. Unter Windows ist int 32 Bit, unter AVR
> 16 Bit. Damit funktioniert die Druckberechnung beim Test unter Windows,
> übertragen auf den AVR aber nicht mehr. BTDT.

Die Portierungsprobleme wegen unterschiedlicher nativer Wortbreite gibt
es auch in Pascal.


Leute, die Unterschiede zwischen C und Pascal sind bei Weitem nicht so
groß, wie es von einigen immer wieder behauptet wird. Ganz im Gegenteil:
Die Unterschiede zwischen den beiden Sprachen an sich sind so marginal,
dass es sich kaum lohnt, sich deswegen in die Haare zu geraten.

Dass sich letztendlich C/C++ gegenüber Pascal/Object-Pascal durchgesetzt
hat, liegt auch überhaupt nicht daran, dass es die bessere Sprache wäre,
sondern hängt ganz einfach damit zusammen, dass sich die C-Familie bzgl.
der

- Nutzbarkeit für reale Anwendungen,

- der Einführung neuer Features wie die Objektorientierung,

- der Verfügbarkeit für verschiedene Plattformen (insbesondere
  Mikrocontroller),

- der Optimierungfähigkeiten der Compiler

- u.v.m.

schneller entwickelt hat als die Pascal-Familie.

Zwar war Pascal 1 bis 2 Jahre früher am Start als C, trotzdem hinkte es
in den o.g. Punkten gegenüber von C immer um mindestens 1 bis 2 Jahre
hinterher.

Es gibt auch durchaus Punkte, bei denen Pascal die Nase vorn hat, aber
offensichtlich reicht dieses Delta nicht aus, um C/C++-Programmierer ins
Pascal-Lager zu locken.

von Uhu U. (uhu)


Lesenswert?

Yalu X. schrieb:
> Die Portierungsprobleme wegen unterschiedlicher nativer Wortbreite gibt
> es auch in Pascal.

Nicht aus Jux und Dollerei verwendet man nicht die nativen Datentypen, 
sondern definiert sich passende, abhängig von INT_MAX & Co. per typedef…

Das sind dann die allseits bekannten int*_t- und uint*_t-Typen.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

Es ist ja nicht mal die Frage nach der Programmiersprache, welche das 
Problem auslöst.
 Vielmehr ist es das mehr oder weniger vorhandene Verständnis der 
Implementation von allgemeingültigen mathematischsymtaktische Ausdrücken 
in konkrete resuorcenbasierte Beschränkungen realer Binärtechniken.

 Alles steht und fällt mit der unterschiedlich stark beschränkten 
Wortbreite sowie der resultierendn Vermengung von Betrag und Signum.

 Wer das nicht verinnerlicht und die Datentypen nicht auseinanderhalten 
kann, kann weder mit manueller noch mit automatischer Typzuweisung 
umgehen, geschweige denn mit impliziten Typumwandlungen. Das ist völlig 
Sprachunabhängig.

Man muss die Regeln kennen sowohl zu korrekten Anwendung, als auch, um 
sie mit korrektem Ergebnis brechen zu können, wie immer im Leben.

Dass (Ur)Pascal restriktiver damit umging ist für Nichtinformatiker von 
Vorteil. Aber die Entwicklung hin zu mehr Comfort zeitigt dort, wie in 
allen Anderen Programmiersprachen, die gleichen Fussangeln, weil diese, 
wie beschrieben, tiefer liegen und struktureller Natur sind und damit 
unabhängig von der syntaktischen Implementierung.

C bietet in sofern mehr dem Programmierer mehr möglichkeiten in dem es 
weniger restriktiv ist. Der Preis ist die höhere Anforderung an der 
Codeentwickler sich über das zu erwartende Ergebnis seiner 
Problemimplementation im klaren zu sein.

Freiheit versus (Eigen)Verantwortung, wie immer im Leben.
Und Kenntniss der Zusammenhänge gibt Freiheit und erfordert 
Selbtstkontroll. Unkenntniss setzt Grenzen.

Namaste

von A. S. (Gast)


Lesenswert?

Uhu U. schrieb:
> Nicht aus Jux und Dollerei verwendet man nicht die nativen Datentypen,
> sondern definiert sich passende, abhängig von INT_MAX & Co. per typedef…

Die einem in der Praxis trotzdem nicht viel weiter helfen.

Integer Promotion und %i kümmern sich wenig um uint16_t. Portabel artet 
das in obfuscating aus, Warnung vor redundanten casts oder 
Bereichsüberschreitungen inklusive.

Und bei der Nutzung verschiedener Compilerwelten sind dann je typedef 
Gräber von #ifdef notwendig, wchar_t macht mich da wahnsinnig.

von Stefan F. (Gast)


Lesenswert?

Man könnte sich genau so gut über Taschenrechner beklagen. Die berechnen 
einige Aufgaben auch nicht sauber nach den Regeln der Mathematik.

Zum Beispiel: ist bei diesen Geräten die Wurzel aus 4 = 2.

Dabei könnte es auch -2 sein, was jeder Taschenrechner verheimlicht. 
Rege Dich doch darüber auf, denn das betrifft noch viel mehr Menschen, 
als die Programmiersprachen.

von Robert L. (lrlr)


Lesenswert?

Thomas M. schrieb:
> weil das nicht Teil dieser Diskussion ist..es geht um die Falle das
> in C einen Fehler verursacht, was auf den ersten Blick unverständlich
> ist!
> Was in Pascal/Delphi, Freepascal/Lazarus PAscal so funktioniert wie man
> es logisch erwartet gibt in C einen bösen Fehler!
> Das von dir genannte Beispiel ist aber für jeden sofort ersichtlich,d as
> es schlicht grob falsch war..klar wäre es gut wenn auch sowas nicht
> durch den Compiler ginge, aber es ist klar ersichtlich, selbst für nicht
> C Programmierer
>
>
1
> //fpc 3.0.0
2
> 
3
> program HelloWorld;
4
> Uses sysutils;
5
> 
6
> var i : Longint;
7
>     a : Integer;
8
>     b : Integer;
9
> 
10
> begin
11
>    a := 30000;
12
>    b := 2;
13
>    i := a * b;
14
> 
15
>     writeln(inttoStr(i));
16
> end.
17
>
>
> zum Onlinecompiler
> https://rextester.com/l/pascal_online_compiler
1
//fpc 3.0.0
2
3
program HelloWorld;
4
Uses sysutils;
5
6
var i : Longint;
7
    a : Word;
8
    b : Word;
9
    
10
begin
11
   a := 30000;
12
   b := 2;
13
   i := a * b;
14
15
    writeln(inttoStr(i));
16
end.

meintest du wahrscheinlich

Warum C-hater ganz oben "-30" für den Beitrag erhält, versteh ich 
nicht.. (inhaltlich hat er Recht, ..)

für die "typischen" C stolperfall  wie "if (a=b) {...}"  gibt es 
inzwischen ja auch Warnungen.. es ist "euch" also durchaus bewusst, wo 
die "schwächen" liegen..

von (prx) A. K. (prx)


Lesenswert?

Robert L. schrieb:
> Warum C-hater ganz oben "-30" für den Beitrag erhält, versteh ich
> nicht.. (inhaltlich hat er Recht, ..)

Du hältst den Begriff "Dreckssprache" für ein passendes Argument? 
Ausserdem hat er eine einschlägige Vorgeschichte als jemand, der Threads 
in die Gosse zieht.

von Einer K. (Gast)


Lesenswert?

Robert L. schrieb:
> Warum C-hater ganz oben "-30" für den Beitrag erhält, versteh ich
> nicht..

Für seine Hasspredigt!
Gerne auch mit täuschen, lügen und Zwietracht sähen.
Üblicher weise, gespickt mit Schimpfworten.

Sobald jemand äußert, mit C oder C++, klar zu kommen rastet er aus.
Wie ein kleines Kind, welches anderen Kindern die Förmchen kaputt tritt. 
Nicht um eines Vorteils willen, sondern aus purem Zerstörungsdrang.


Meine vorläufige Diagnose:
Neurotische Fehlanpassung, mit starken antisozialen Tendenzen.

von Robert L. (lrlr)


Lesenswert?

>"Dreckssprache"
nein,
aber wenn man dafür ein "schöneres Wort" ("unintuitiv" oder ähnliches) 
einfügt, und den Rest vom Posting liest, hat er grundsätzlich recht..

ok -30 für Populismus.. , ja kann man durchgehen lassen..

: Bearbeitet durch User
von Purzel H. (hacky)


Lesenswert?

> Fast alle Programmiersprachen verhalten sich so.

Nun, man muss eigentlich nur einer Konstanten einen Typ vorschreiben. 
Was man ja kann.

von Einer K. (Gast)


Lesenswert?

Name H. schrieb:
> Nun, man muss eigentlich nur einer Konstanten einen Typ vorschreiben.
> Was man ja kann.

Natürlich!

Der Code im Eingangsposting arbeitet mit magischen Zahlen im Code.
Das ist schlechter Stil.
Nebenbei führt das auch zu dem eingangs genannten Überlauf Problemen.



Besser ist sowas:
1
const uint32_t value  = 30000;
2
const uint32_t faktor = 2; // hier kann man auch einen kleineren Type wählen
3
4
5
6
void setup() {
7
  Serial.begin(9600);
8
9
  uint32_t i = 30000 * 2; // Das ergibt keine 60000, sondern 4294934528
10
  Serial.println(i);
11
12
  uint32_t ergebnis = value * faktor; // Das ergibt 60000
13
  Serial.println(ergebnis);
14
}
15
16
void loop() {
17
}

Etwas mehr Schreibarbeit, aber in vielerlei Hinsicht sauberer.

Ob man Konstanten und
> uint32_t ergebnis = value * faktor; // Das ergibt 60000
oder
> uint32_t ergebnis = 30000 * 2UL; // Das ergibt 60000
verwendet, hat keine Auswirkung auf das Laufzeitverhalten. Es wird der 
gleiche Code erzeugt



----

Und wie schon von mehreren gesagt:
Wenn man die Warnungen abschaltet, oder abgeschaltet lässt, darf man von 
dem Verhalten überrascht sein.

Aber Warnungen zu ignorieren, gehört meist in den Bereich Dummheit
1
E:\Programme\arduino\portable\sketchbook\Forum\sketch_mar12a\sketch_mar12a.ino: In function 'void setup()':
2
3
E:\Programme\arduino\portable\sketchbook\Forum\sketch_mar12a\sketch_mar12a.ino:10:22: warning: integer overflow in expression [-Woverflow]
4
5
   uint32_t i = 30000 * 2; // Das ergibt keine 60000, sondern 4294934528
6
7
                ~~~~~~^~~

von Uhu U. (uhu)


Lesenswert?

Stefanus F. schrieb:
> Dabei könnte es auch -2 sein, was jeder Taschenrechner verheimlicht.

Er verheimlicht es nicht, er setzt voraus, dass der Nutzer die 
Grundbegriffe kennt ;-)

von Thomas E. (thomase)


Lesenswert?

Stefanus F. schrieb:
> Zum Beispiel: ist bei diesen Geräten die Wurzel aus 4 = 2.
>
> Dabei könnte es auch -2 sein, was jeder Taschenrechner verheimlicht.

-2, 2

Das würden viele Experten aber als Minus Zweikommazwei lesen. Deshalb 
lass es lieber wie es ist. Wen es interessiert, der kommt da auch so mit 
klar.

von Christopher C. (trihexagon)


Lesenswert?

A. S. schrieb:
> Uhu U. schrieb:
>> Nicht aus Jux und Dollerei verwendet man nicht die nativen Datentypen,
>> sondern definiert sich passende, abhängig von INT_MAX & Co. per typedef…
>
> Die einem in der Praxis trotzdem nicht viel weiter helfen.
>
> Integer Promotion und %i kümmern sich wenig um uint16_t. Portabel artet
> das in obfuscating aus, Warnung vor redundanten casts oder
> Bereichsüberschreitungen inklusive.

Wo ist das Problem?
1
#include <stdio.h>
2
#include <inttypes.h>
3
4
int main()
5
{
6
    uint32_t val = UINT32_C(30000) * 2;
7
    printf("%"PRId32"\n", val);
8
9
    return 0;
10
}

von Robert L. (lrlr)


Lesenswert?

Besser ist sowas:

const uint32_t value  = 30000;
const uint32_t faktor = 2; // hier kann man auch einen kleineren Type 
wählen

warum?
mit welcher Begründung bei 2 ??

bei 30000 könnte man auch "hier kann man auch einen kleineren Type 
wählen" hinschreiben

das Problem ist im Kern das Selbe.. nur um ein paar Zeilen nach oben 
verschoben..

was ist eigentlich der Nachteil, so wie es Pascal macht?

https://rextester.com/LWBNU8599

: Bearbeitet durch User
von Karl K. (karl2go)


Lesenswert?

Arduino Fanboy D. schrieb:
> Etwas mehr Schreibarbeit, aber in vielerlei Hinsicht sauberer.

Im Gegenteil: Da wird sich jeder erstmal fragen: Häh? Eine 30000 passt 
in ein int16, warum nimmt er hier ein uint32 und verschwendet Speicher. 
Denn das später mit der 30000 der int16 übeschrietten wird ist an der 
Stelle nicht ersichtlich.

Konsequent fortgeführt, müsste ich alle adc_mean-Variablen mit uint32 
führen, weil irgendwann mal mit einem Faktor verrechnet um von 1024 
Counts auf 5000mV umzurechnen. Da würde ich mir den Code aber schön 
aufblähen.

Sämtliche Divisionen mit shr würden doppelt so lang, obwohl ich den 
adc_mean nur durch 16 teile - was immer noch gut in uint16 passt.

Und der Tiefpassfilter, der mit 15 multipliziert, müsste statt 3x mul - 
was immer noch in uint16 passt, eine 32-Bit Multiplikation in Software 
heranziehen.

Merkst Du, was Du Dir da heranziehst?

Sauber wäre: Die Konstanten und Variablen mit dem Wertebereich zu 
erzeugen, in den sie passen, und dann bei der Berechnung zu casten.
1
const uint16_t value  = 30000;
2
const uint8_t faktor = 2;
3
4
void setup() {
5
  Serial.begin(9600);
6
7
  uint32_t i = uint32_t(30000) * 2;
8
  Serial.println(i);
9
10
  uint32_t ergebnis = value * faktor; // muss man nicht casten, denn 60000 passt immer noch in uint16
11
  Serial.println(ergebnis);
12
13
  uint32_t ergebnis = uint32(value) * faktor * faktor;
14
  Serial.println(ergebnis);
15
}
16
17
void loop() {
18
}

Prinzipiell ist es auf dem AVR sinnvoll, möglicht mit uint zu arbeiten, 
denn mit int werden einige Operationen deutlich aufwendiger, obwohl sie 
das gleiche bewirken.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl K. schrieb:
> Sauber wäre: Die Konstanten und Variablen mit dem Wertebereich zu
> erzeugen, in den sie passen, und dann bei der Berechnung zu casten.

Korrekt. Eine Variable vorsichtshalber (um nicht zu sagen: aus Angst) 
mit dem größten noch einigermaßen praktikablen Datentyp anzulegen ist 
nicht zielführend.

Gerade, wenn ich so einen Angst-Code beispielsweise irgendwo lese, dann 
denke ich sofort: Da hat er etwas Grundlegendes nicht verstanden und hat 
sein Unwissen mit der Keule kaschiert.

> Sämtliche Divisionen mit shr würden doppelt so lang, obwohl ich den
> adc_mean nur durch 16 teile - was immer noch gut in uint16 passt.

Ja, genau in diese Schere würde man laufen.

Man kann Stefan aber noch zugute halten, dass er die beiden Variablen 
wenigstens mit "const" angelegt hat, so dass der Compiler wenigstens 
noch etwas herausholen kann.

von Uhu U. (uhu)


Lesenswert?

A. S. schrieb:
> Uhu U. schrieb:
>> Nicht aus Jux und Dollerei verwendet man nicht die nativen Datentypen,
>> sondern definiert sich passende, abhängig von INT_MAX & Co. per typedef…
>
> Die einem in der Praxis trotzdem nicht viel weiter helfen.

Na du scheinst ja ein sehr erfahrener Autor portabler Programme zu sein…

Komisch nur, dass z.B. der Brocken Linux mit all seinen vielen Tools das 
problemlos auf die Reihe bekommt.

Können die Jungs etwa zaubern? Oder pflegen die für jedes Integerformat 
eine eigene Version?

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Karl K. schrieb:
> Im Gegenteil: Da wird sich jeder erstmal fragen: Häh? Eine 30000 passt
> in ein int16, warum nimmt er hier ein uint32 und verschwendet Speicher.
> Denn das später mit der 30000 der int16 übeschrietten wird ist an der
> Stelle nicht ersichtlich.

Das ist eine Konstante und in diesem konkreten Beispiel ist Speicher 
Verbrauch nicht von belang, da es zur Kompilezeit berechnet wird,

Frank M. schrieb:
> Man kann Stefan aber noch zugute halten, dass er die beiden Variablen
> wenigstens mit "const" angelegt hat, so dass der Compiler wenigstens
> noch etwas herausholen kann.

Ich bin nicht Stefan!
Und genau aus dem Grund sind die Dinge Konstant.
Denn: Im Eingangsbeispiel sind sie auch konstant.

Karl K. schrieb:
> Merkst Du, was Du Dir da heranziehst?
Du veränderst die Ausgangslage und machst aus Konstanten Variablen.
Bemerkst Du, deine Verfälschung?

Merke:
Andere Ausgangsbedingung/Aufgabenstellung, andere Lösung.

von Purzel H. (hacky)


Lesenswert?

>Stefanus :
>Man könnte sich genau so gut über Taschenrechner beklagen. Die berechnen
einige Aufgaben auch nicht sauber nach den Regeln der Mathematik.
>
>Zum Beispiel: ist bei diesen Geräten die Wurzel aus 4 = 2.
> Dabei könnte es auch -2 sein, was jeder Taschenrechner verheimlicht.

Nein, ist leider nicht richtig.
   wurzel(4) = 2
 aber die Gleichung
   a= wurzel(4)
 hat fuer a zwei Loesungen { +2 & -2 }

Fuer 3.wurzel(x) gibt es drei loesungen, aber nur eine wurzel. Dies, 
weil wurzel(x) eine Funktion ist, bedeutet ein Input, ein Output. Und 
was du meinst ist eine Gleichung.

Ja, ist spitzfindig. Mathematik eben.

von Thomas E. (thomase)


Lesenswert?

Robert L. schrieb:
> Warum C-hater ganz oben "-30" für den Beitrag erhält, versteh ich
> nicht.. (inhaltlich hat er Recht, ..)

-25 kriegt er, weil er c-hater ist, nochmal -25 für seine Ausdrucksweise 
und wenn er Recht hat, geht das wieder um 20 nach oben.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Uhu U. schrieb:
> A. S. schrieb:
>> Uhu U. schrieb:
>>> Nicht aus Jux und Dollerei verwendet man nicht die nativen Datentypen,
>>> sondern definiert sich passende, abhängig von INT_MAX & Co. per typedef…
>>
>> Die einem in der Praxis trotzdem nicht viel weiter helfen.
>
> Na du scheinst ja ein sehr erfahrener Autor portabler Programme zu sein…
>
> Komisch nur, dass z.B. der Brocken Linux mit all seinen vielen Tools das
> problemlos auf die Reihe bekommt.

Hast du mal darüber nachgedacht, warum Linux nur auf Plattformen läuft,
wofür es

1. einen GCC gibt und

2. int 32 Bit breit ist?

Dafür gibt es natürlich viele Gründe, aber das hier dürfte einer von
ihnen sein.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> warum Linux nur auf Plattformen läuft,
> wofür es
> 1. einen GCC gibt und
>
> 2. int 32 Bit breit ist?

Ist int auf x86_64 unter Linux nicht 64 Bit breit?

von Vn N. (wefwef_s)


Lesenswert?

Yalu X. schrieb:
> Hast du mal darüber nachgedacht, warum Linux nur auf Plattformen läuft,
> wofür es
>
> 1. einen GCC gibt und
>
> 2. int 32 Bit breit ist?

Zumindest der Kernel lässt sich AFAIK auch mit LLVM bauen, und fürs 
zweite hätte ich gern eine Quelle. Normal ist eher die MMU das 
limitierende. Mir fällt leider keine halbwegs aktuelle 
16-Bit-Architektur mit MMU ein.

von (prx) A. K. (prx)


Lesenswert?

Yalu X. schrieb:
> Hast du mal darüber nachgedacht, warum Linux nur auf Plattformen läuft,
> wofür es
>
> 1. einen GCC gibt und
>
> 2. int 32 Bit breit ist?

Es gab auch Linux für DEC Alpha. Im ILP64 Programmiermodell, also mit 
64-Bit int.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Rufus Τ. F. schrieb:
>>
>
> Ist int auf x86_64 unter Linux nicht 64 Bit breit?
1
# cat bit.c && cc bit.c -o bit && ./bit
2
#include <stdio.h>
3
4
int main ()
5
{
6
    printf ("int  %d\n", sizeof (int));
7
    printf ("long %d\n", sizeof (long));
8
    return 0;
9
}
1
int  4
2
long 8
1
# uname -a
2
Linux xxx.de 4.9.0-6-amd64 #1 SMP Debian 4.9.82-1+deb9u2 (2018-02-21) x86_64 GNU/Linux

: Bearbeitet durch Moderator
von (prx) A. K. (prx)


Lesenswert?

Rufus Τ. F. schrieb:
> Ist int auf x86_64 unter Linux nicht 64 Bit breit?

Nein. Das ist LP64, also 32-Bit int und 64-Bit long/pointer. Zu den 
Gründen mag zählen, dass es in ILP64 keine im Standard vorkommenden 
Typen für 16 und 32 Bits gibt. Für eines von beiden müsste ein 
proprietärer Typ her.

Windows ist LLP64, 32-bit int und long, 64 bit long long / pointer.

https://de.wikipedia.org/wiki/64-Bit-Architektur#Programmiermodell

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

vn n. schrieb:
> Yalu X. schrieb:
>> Hast du mal darüber nachgedacht, warum Linux nur auf Plattformen läuft,
>> wofür es
>>
>> 1. einen GCC gibt und
>>
>> 2. int 32 Bit breit ist?
>
> Zumindest der Kernel lässt sich AFAIK auch mit LLVM bauen,

Kann schon sein, zumal Clang sich Mühe gibt, weitgehend GCC-kompatibel
zu sein, um als Ersatz für diesen dienen zu können. Ich glaube aber
nicht, dass sich die Kernel-Entwickler darauf verlassen wollen, dass das
immer so ist, deswegen ist der Standard-Compiler für den Kernel immer
noch GCC.

> und fürs zweite hätte ich gern eine Quelle.

Zwar schon etwas älter, aber daran dürfte sich seither nicht viel
geändert haben:
1
Obwohl es keine Regel gibt, dass ein int 32 Bits sein muss, ist dies auf
2
allen aktuell unterstützten Plattformen der Fall.

Aus: Robert Love: Linux-Kernel Handbuch. Leitfaden zu Design und
Implementierung von Kernel 2.6. Übersetzt von Erik Keller.
Addison-Wesley 2005, S. 409.

A. K. schrieb:
> Es gab auch Linux für DEC Alpha. Im ILP64 Programmiermodell, also mit
> 64-Bit int.

Danke, das habe ich nicht gewusst. Ein int größer als die üblichen 32
Bit sollte aber kein Problem darstellen, wenn bei der Programmierung
kein Schindluder getrieben wird wie bspw. die gezielte Nutzung von
Overflows in unsigned int. Mit Problemen wäre vor allem auf Plattformen
mit kleinerem int (bspw. 16 Bit) zu rechnen, da ist mir aber keine
bekannt, auf der Linux (oder auch nur µCLinux) läuft.

von Uhu U. (uhu)


Lesenswert?

Yalu X. schrieb:
> Hast du mal darüber nachgedacht, warum Linux nur auf Plattformen läuft,
> wofür es
>
> 1. einen GCC gibt und
>
> 2. int 32 Bit breit ist?
>
> Dafür gibt es natürlich viele Gründe, aber das hier dürfte einer von
> ihnen sein.

Hier kannst du nachlesen, wie der Linux-Quellcode portabel gemacht wird:

   https://lwn.net/images/pdf/LDD3/ch11.pdf

von Walter K. (vril1959)


Lesenswert?

Yalu X. schrieb:
> Ich glaube aber
> nicht, dass sich die Kernel-Entwickler darauf verlassen wollen, dass das
> immer so ist, deswegen ist der Standard-Compiler für den Kernel immer
> noch GCC.

Naja .. Linux braucht manchmal halt etwas länger;-)

Aber bei "echten" Unix wie MacOS oder den BSDs siehts anders aus:

Clang / LLVM ist der System-Compiler in FreeBSD 10.0 und höher, und GCC 
wird standardmäßig nicht installiert.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Uhu U. schrieb:

> [Kernel]
> Können die Jungs etwa zaubern?

Ja ;-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Uhu U. schrieb:
> Hier kannst du nachlesen, wie der Linux-Quellcode portabel gemacht wird:
>
>    https://lwn.net/images/pdf/LDD3/ch11.pdf

Danach ist int auf allen unterstützten Architekturen 32 Bit breit, sogar
auf DEC-Alpha, so dass es bzgl. Integer-Promotion tatsächlich zu keinen
Problemen kommen kann. Und für kritische Variablen kann man ja, wie du
oben schon schriebst, die Typen mit festdefinierter Bitbreite verwenden.

Die Portierung von 32- auf 8-Bit-Prozessoren gestaltet sich aber wegen
der unterschiedlichen int-Größe meist etwas schwieriger. Deswegen gab es
hier im Forum vor kurzem auch eine Anfrage, wie man C-Programme auf dem
PC mit 16-Bit-int kompilieren und ausführen kann, um bspw. komlexere
Rechenalgorithmen auf dem PC vortesten zu können, bevor sie auf den µC
übertragen werden.

Man kann, um die Portabilität zu erhöhen, den Einfluss der Integer-
Promotion auch komplett ausschalten, indem man alle (Teil-)Ausdrücke –
wo erforderlich – geeignet castet. Nur will dann niemand mehr den
verunstalteten Code lesen :)

von Vn N. (wefwef_s)


Lesenswert?

Yalu X. schrieb:
> Zwar schon etwas älter, aber daran dürfte sich seither nicht viel
> geändert haben:
> Obwohl es keine Regel gibt, dass ein int 32 Bits sein muss, ist dies auf
> allen aktuell unterstützten Plattformen der Fall.
>
> Aus: Robert Love: Linux-Kernel Handbuch. Leitfaden zu Design und
> Implementierung von Kernel 2.6. Übersetzt von Erik Keller.
> Addison-Wesley 2005, S. 409.

Also ich lese dort nicht raus, dass Linux sich nicht für eine Plattform 
< 32 Bit übersetzen lassen soll, lediglich, dass es aktuell keine solche 
gibt.
Womit wir wieder beim Thema wären, dass Linux eine MMU haben will, und 
mir kein aktueller Prozessor mit 8 oder 16 bit und eingebauter MMU 
einfallen will.

von (prx) A. K. (prx)


Lesenswert?

Yalu X. schrieb:
> Danach ist int auf allen unterstützten Architekturen 32 Bit breit, sogar
> auf DEC-Alpha,

Scheint auch logischer, weil man sonst mit einem 16-Bit Typ Probleme 
hat. Die Wikipedia-D erzählt da wohl Mist, die -E enthält das nicht.

von Uhu U. (uhu)


Lesenswert?

Yalu X. schrieb:
> Man kann, um die Portabilität zu erhöhen, den Einfluss der Integer-
> Promotion auch komplett ausschalten, indem man alle (Teil-)Ausdrücke –
> wo erforderlich – geeignet castet. Nur will dann niemand mehr den
> verunstalteten Code lesen :)

Wieso alle Teilausdrücke und wieso casten?

Es reicht ein einziges mal der Typ-Postfix an eine Konstante, dann wird 
der gesamte Ausdruck in mindestens dieser Länge berechnet und wenn keine 
Konstante vorkommt, reicht es, eine Variable geeignet zu casten.

von Yalu X. (yalu) (Moderator)


Lesenswert?

vn n. schrieb:
> Also ich lese dort nicht raus, dass Linux sich nicht für eine Plattform
> < 32 Bit übersetzen lassen soll, lediglich, dass es aktuell keine solche
> gibt.

Dass es keine gibt, reicht ja schon, um dem Integer-Promotion-Problem
aus dem Weg zu gehen.


Uhu U. schrieb:
> Wieso alle Teilausdrücke und wieso casten?
>
> Es reicht ein einziges mal der Typ-Postfix an eine Konstante, dann wird
> der gesamte Ausdruck in mindestens dieser Länge berechnet und wenn keine
> Konstante vorkommt, reicht es, eine Variable geeignet zu casten.

In

  a * b + c * d

müssen für sizeof(int)=sizeof(x)=2 (x∈{a,b,c,d}) und a*b ≥ 65536 ≤ c*d
mindestens zwei Operanden (bspw. a und c) gecastet werden. Das sieht zum
einen nicht schön aus, zum anderen vergisst man bei komplizierteren
Ausdrücken schnell mal einen Cast.

von Vn N. (wefwef_s)


Lesenswert?

Yalu X. schrieb:
> Dass es keine gibt, reicht ja schon, um dem Integer-Promotion-Problem
> aus dem Weg zu gehen.

Du hast aber impliziert, dass es nicht möglich wäre, Linux für 
Plattformen unter 32 Bit zu übersetzen. Und das ist keineswegs bewiesen, 
nur weil es halt keine solche Plattform (mangels Existenz) gibt. 16 Bit 
mit MMU fallen mir nur pProzessoren ein, die lange vor Linux aktuell 
waren...

von Uhu U. (uhu)


Lesenswert?

Yalu X. schrieb:
> In
>
>   a * b + c * d
>
> müssen für sizeof(int)=sizeof(x)=2 (x∈{a,b,c,d}) und a*b ≥ 65536 ≤ c*d

Kannst du die Regeln zitieren, aus denen das folgt?

Beitrag #5768684 wurde von einem Moderator gelöscht.
von Vn N. (wefwef_s)


Lesenswert?

A. S. schrieb im Beitrag #5768684:
> natürlich weiss ich, dass es auf 16-Bit-Maschinen TRUE und auf
> 32-Bit-Maschinen /(meist)/ FALSE ist

Bitte wo soll das der Fall sein, und warum?

A. S. schrieb im Beitrag #5768684:
> aber bin ich mir dessen immer
> bewusst? [...] Nein.

Tja, jede Programmiersprache hat halt so ihre Regeln, die man kennen und 
beachten sollte, egal ob es nun C ist oder Brainfuck. Ist halt so. Wenn 
dir C nicht gefällt, wechsle halt.

von Yalu X. (yalu) (Moderator)


Lesenswert?

vn n. schrieb:
> Yalu X. schrieb:
>> Dass es keine gibt, reicht ja schon, um dem Integer-Promotion-Problem
>> aus dem Weg zu gehen.
>
> Du hast aber impliziert, dass es nicht möglich wäre, Linux für
> Plattformen unter 32 Bit zu übersetzen. Und das ist keineswegs bewiesen

Nein, bewiesen ist das nicht, aber ich halte es angesichts der riesigen
Codebasis für sehr, sehr wahrscheinlich, dass es da zu Problemen kommt.

Aber selbst wenn der Kernel ohne Änderung auch für 16-Bit-Systeme
lauffähig wäre, wäre das eher Glückssache und deswegen schlecht als
Begründung dafür geeignet, dass die Integer-Promotion bei der Portierung
von einem 32- auf ein 16- oder 8-Bit-Plattform niemals Probleme macht.
Uhus Aussage von oben impliziert aber genau dies.


Uhu U. schrieb:
> Yalu X. schrieb:
>> In
>>
>>   a * b + c * d
>>
>> müssen für sizeof(int)=sizeof(x)=2 (x∈{a,b,c,d}) und a*b ≥ 65536 ≤ c*d
>
> Kannst du die Regeln zitieren, aus denen das folgt?

Das kann man ganz einfach an einem Beispiel erklären (int sei 16 Bit
breit):

1
#include <stdio.h>
2
#include <inttypes.h>
3
4
int main(void) {
5
  uint16_t a = 1000, b = 1000, c = 1000, d = 1000;
6
  uint32_t e1 = a * b + c * d;
7
  uint32_t e2 = (uint32_t)a * b + c * d;
8
  uint32_t e3 = (uint32_t)a * b + (uint32_t)c * d;
9
  printf("e1=%"PRIu32" e2=%"PRIu32" e3=%"PRIu32"\n", e1, e2, e3);
10
}

Ausgabe:

1
e1=33920 e2=1016960 e3=2000000

Im ersten Fall überlaufen beide Teilprodukte, im zweiten nur eins und im
dritten überhaupt keins. Deswegen braucht man bspw. auf einem AVR beide
Casts, auf einem PC mit 32-Bit-int kann man sich beide sparen.

von Karl K. (karl2go)


Lesenswert?

Arduino Fanboy D. schrieb:
> Du veränderst die Ausgangslage und machst aus Konstanten Variablen.

Ja, das war die Vorgabe: Der Compiler muss sich bei 30000 * 2 
verrechnen, egal ob es eine Konstante oder eine Variable ist. Damit das 
immer gleich falsch ist. Wurde mir oben so erklärt.

Also bitte, wenn schon - denn schon, nicht mal so mal so, wie es euch 
gerade in den Kram passt.

von Karl K. (karl2go)


Lesenswert?

Uhu U. schrieb:
> A. S. schrieb:
>> Uhu U. schrieb:
>>> Nicht aus Jux und Dollerei verwendet man nicht die nativen Datentypen,
>> Die einem in der Praxis trotzdem nicht viel weiter helfen.
> Na du scheinst ja ein sehr erfahrener Autor portabler Programme zu sein…

Na Du scheinst ja nicht viel Erfahrung zu haben.

Die Druckberechnung für den BMP180 - genauso bescheiden wie für den 
BME280 - am PC zusammengebaut und mit vom AVR ausgelesenen Rohwerten am 
PC getestet. Funktioniert.

Die Routine auf den AVR übernommen: Funktioniert nicht.

Am PC hat der Compiler auch für als uint16, int16 definierte Variablen 
32 Bit verwendet bzw. Multiplikationen auch in 32 Bit ausgeführt und die 
Berechnungen liefen ohne Überlauf durch.

Am AVR hat der Compiler dann die angegeben 16 Bit verwendet bzw. 
Multiplikationen auch nur mit 16 Bit ausgeführt, und das ging halt 
schief.

War ein Test, aber: Nein, man kann nicht davon ausgehen, dass man mit 
uint16... sicher plattformübergreifend ist.

von Rolf M. (rmagnus)


Lesenswert?

Yalu X. schrieb:
> Hast du mal darüber nachgedacht, warum Linux nur auf Plattformen läuft,
> wofür es
>
> 1. einen GCC gibt und

Hauptsächlich weil Linus Torvalds nix von Standard-C hält und massiv 
GCC-Erweiterungen nutzt. Das macht es anderen Compilern extrem schwer, 
den Kernel zu übersetzen. Intel hat mal sehr viel Arbeit reingesteckt, 
deren Compiler so weit zu bringen, dass der Kernel damit auch 
übersetztbar war.

> 2. int 32 Bit breit ist?

Linux setzt die POSIX-Spezifikation um, die für int eine Mindestgröße 
von 32 Bit fordert.

A. K. schrieb:
> Rufus Τ. F. schrieb:
>> Ist int auf x86_64 unter Linux nicht 64 Bit breit?
>
> Nein. Das ist LP64, also 32-Bit int und 64-Bit long/pointer. Zu den
> Gründen mag zählen, dass es in ILP64 keine im Standard vorkommenden
> Typen für 16 und 32 Bits gibt. Für eines von beiden müsste ein
> proprietärer Typ her.

Ich denke, das wird der Hauptgrund sein. Eigentlich sollte int der 
native Typ der Zielplattform sein (das ist in ISO C nicht gefordert, 
aber dass es so gedacht ist, wird dort durchaus erwähnt). Bei 
64-Bit-Plattformen würden einem aber die kleineren Typen ausgehen, also 
belässt man es in der Regel bei 32 Bit.

Uhu U. schrieb:
> Yalu X. schrieb:
>> Man kann, um die Portabilität zu erhöhen, den Einfluss der Integer-
>> Promotion auch komplett ausschalten, indem man alle (Teil-)Ausdrücke –
>> wo erforderlich – geeignet castet. Nur will dann niemand mehr den
>> verunstalteten Code lesen :)
>
> Wieso alle Teilausdrücke und wieso casten?
>
> Es reicht ein einziges mal der Typ-Postfix an eine Konstante, dann wird
> der gesamte Ausdruck in mindestens dieser Länge berechnet und wenn keine
> Konstante vorkommt, reicht es, eine Variable geeignet zu casten.

Da hast du glaub ich falsch rum gedacht. Es ging meinem Verständnis nach 
darum, auf dem PC einen Algorithmus für den AVR zu testen und dabei 
nicht in die Falle zu tappen, dass Dinge aufgrund der 32-Bit-Integer auf 
dem PC funktionieren, die auf dem AVR ggf. fehlschlagen würden.

vn n. schrieb:
> Du hast aber impliziert, dass es nicht möglich wäre, Linux für
> Plattformen unter 32 Bit zu übersetzen. Und das ist keineswegs bewiesen,
> nur weil es halt keine solche Plattform (mangels Existenz) gibt.

Dass das out of the box geht, halte ich auch für sehr unwahrscheinlich.

> 16 Bit mit MMU fallen mir nur pProzessoren ein, die lange vor Linux
> aktuell waren...

Wobei eine MMU nicht zwingend nötig ist.
https://de.wikipedia.org/wiki/%CE%9CClinux

Karl K. schrieb:
> Am PC hat der Compiler auch für als uint16, int16 definierte Variablen
> 32 Bit verwendet

Ein uint16_t ist 16 Bit breit. Immer.

> bzw. Multiplikationen auch in 32 Bit ausgeführt

Das schon eher, da - wie schon erwähnt wurde - alle Berechnungen 
mindestens in int ausgeführt werden, also auf dem PC in 32 Bit.

: Bearbeitet durch User
von Uhu U. (uhu)


Lesenswert?

Karl K. schrieb:
> Am PC hat der Compiler auch für als uint16, int16 definierte Variablen
> 32 Bit verwendet bzw. Multiplikationen auch in 32 Bit ausgeführt und die
> Berechnungen liefen ohne Überlauf durch.

Weißt du nicht, dass c kleinere Integertypen, als int, bei der 
Parameterübergabe immer auf int erweitert?

Parameter sind bei call by value immer mindestens sizeof int lang.

von (prx) A. K. (prx)


Lesenswert?

Uhu U. schrieb:
> Weißt du nicht, dass c kleinere Integertypen, als int, bei der
> Parameterübergabe immer auf int erweitert?

Mit Prototypes werden die Parameter in der Funktion so verwendet, wie 
sie im Prototype deklariert sind. Die genaue Technik der Übergabe ist 
zwar Sache des ABI und kann eine Übergabe als "int" zur Folge haben, 
aber ein Parameter von Typ char wird in der Funktion unabhängig davon 
als char verwendet, mit sizeof(param)==1.

Implizite "int" Konvertierung gibt es nur bei unvollständigen 
Prototypes, also in Funktionen mit variabler Anzahl Parameter wie 
printf, sowie bei fehlenden Prototypes im alten K&R Stil.

: Bearbeitet durch User
von Karl K. (karl2go)


Lesenswert?

Uhu U. schrieb:
> Weißt du nicht, dass c kleinere Integertypen, als int, bei der
> Parameterübergabe immer auf int erweitert?

Mööp: Nein, nicht auf dem AVR.

von Axel S. (a-za-z0-9)


Lesenswert?

Uhu U. schrieb:
> Weißt du nicht, dass c kleinere Integertypen, als int, bei der
> Parameterübergabe immer auf int erweitert?

Hoffentlich "weiß" das niemand. Das wäre nämlich dann falsch.

Was du vermutlich meinst: in Abwesenheit eines Prototyps (vulgo: 
Deklaration) nimmt C für alle Parameter einer Funktion ebenso wie für 
den Rückgabewert int an. Ganz andere Baustelle.

von Jobst Q. (joquis)


Lesenswert?

Winfried J. schrieb:
> C bietet in sofern mehr dem Programmierer mehr möglichkeiten in dem es
> weniger restriktiv ist. Der Preis ist die höhere Anforderung an der
> Codeentwickler sich über das zu erwartende Ergebnis seiner
> Problemimplementation im klaren zu sein.
>
> Freiheit versus (Eigen)Verantwortung, wie immer im Leben.

Wieso "versus" ? Eigenverantwortung lernt man nur in Freiheit. Wenn man 
die Konsequenzen eigener Entscheidungen zu spüren bekommt. Und garnicht 
erst auf die Idee kommt, die Schuld bei anderen zu suchen, von denen man 
ungenügend betreut und kontrolliert wurde.

von Dirk B. (dirkb2)


Lesenswert?

Uhu U. schrieb:
> Weißt du nicht, dass c kleinere Integertypen, als int, bei der
> Parameterübergabe immer auf int erweitert?

Das gilt für Funktionen mit variabler Parameterliste wie z.B. printf und 
scanf.
Dort wird statt float auch double benutzt.
Deswegen ist auch kein %lf bei printf nötig.

Bei scanf werden aber meist Adressen übergeben. Da ist ein %lf nötig.

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.