Hallo, Ich habe einige CUnit-Tests die unter MinGW (32 Bit bzw. 64 Bit) compilieren und durchlaufen! Mein Zielsystem ist ein 16 Bit XE167 (Keil Compiler) und da laufen nicht immer alle Tests durch die zuvor auf dem GCC okay sind. :-( Ich kann nicht immer auf dem Zielsystem testen, leider! Kann ich vielleicht ein paar setting unter GCC vornehmen, sodass er sich eher verhält wie der 16 Bit Keil Compiler? Es geht nur um Arithmetik nicht um HW Register Zugriffe etc. habe natürlich im Netz schon gesucht aber noch nicht das richtige gefunden! Vielleicht hat ja jemand einen Link oder ein paar Tipps beiseite! Danke im Voraus
mgiaco schrieb: > Kann ich vielleicht ein paar setting unter GCC vornehmen, sodass er sich > eher verhält wie der 16 Bit Keil Compiler? Vielleicht statt eines Host-GCC einen Cross-GCC für einen 16-bit-Prozessor (AVR, MSP430) benutzen?
Der Keil läuft doch unter ner IDE (µVision) und da ist doch bestimmt ein Simulator für das Zielsystem dabei. Oder man definiert sich unter dem 32Bit-System 16- und 8-Bit Typen (uint8_t, uint16_t usw.), wenn es die nicht schon gibt. Dann müssen die sich auch gleich verhalten. Wenn man aber int oder long nimmt und die sind mal 16, 32 oder 64 Bit lang, das muß natürlich schief gehen. "int" und "long" sind bei Rechnungen, die eine bestimmte Bitbreite erfordern, Pfui-Bäh! Peter
Jörg Wunsch schrieb: > mgiaco schrieb: >> Kann ich vielleicht ein paar setting unter GCC vornehmen, sodass er sich >> eher verhält wie der 16 Bit Keil Compiler? > > Vielleicht statt eines Host-GCC einen Cross-GCC für einen > 16-bit-Prozessor (AVR, MSP430) benutzen? Das damit generierte Compilat wird dann aber auf dem PC nicht laufen, was - so wie ich es verstanden habe - das Ziel ist. Er will Unit-Tests seiner µC-Software auf dem PC machen. Das halte ich aber eh nicht für sinnvoll. Wenn Portabilität wichtig ist, kann es sinnvoll sein, es zusätzlich auf dem PC zu testen, ansonsten sind Tests, die man nicht auf der Zielplattform, sondern stattdessen auf einer anderen macht, grad für die Tonne. Peter Dannegger schrieb: > "int" und "long" sind bei Rechnungen, die eine bestimmte Bitbreite > erfordern, Pfui-Bäh! Ebenth, aber wenn er die irgendwo verwendet, kann es z.B. sein, daß auf dem PC alles ok aussieht, aber auf dem Zielsystem ein Überlauf passiert. Der Test kann das nicht erkennen.
Peter Dannegger schrieb: > Der Keil läuft doch unter ner IDE (µVision) und da ist doch bestimmt ein > Simulator für das Zielsystem dabei. Ein Simulator für automatisierte Tests ist nur dann brauchbar, wenn er "fernsteuerbar" ist. Man will ja noicht 100 oder 1000 Tests oder noch mehr per Hand in der IDE durchnudeln... > Oder man definiert sich unter dem 32Bit-System 16- und 8-Bit Typen > (uint8_t, uint16_t usw.), wenn es die nicht schon gibt. > Dann müssen die sich auch gleich verhalten. Ja, wieso das denn? Die int-Promotion Rules gibe es doch immer noch. > Wenn man aber int oder long nimmt und die sind mal 16, 32 oder 64 Bit > lang, das muß natürlich schief gehen. > > "int" und "long" sind bei Rechnungen, die eine bestimmte Bitbreite > erfordern, Pfui-Bäh! Unabhängig davon gibt es noch viele andere Sachen ausser int und long die durch die Implementierung festgelegt werden, float- und double- Darstellung etwa, Diagnostics, Anzahl signifikanter Stellen in Identifiern, Include-Regeln, Signness vor char, Struktur-Layout, Data-Alignment, etc.
Peter Dannegger schrieb: > "int" und "long" sind bei Rechnungen, die eine bestimmte Bitbreite > erfordern, Pfui-Bäh! Ach ja? Na dann guck mal, was nach dem Preprozessor aus uint8_t, uint16_t usw. übrig bleibt. Das ist derselbe Quark wie __IO, __I und __O, aus denen ein schlichtes volatile nach dem Preprozessor wird. Ich halte überhaupt nichts von solchen Pseudo-Typen wie uint8_t und Konsorten, weil das alles nur Unleserlichkeiten mit sich bringt, die vom Preprozessor sowieso wieder gnadenlos aus der Quelle herausgeschmissen werden. Wenn man einigermaßen sichergehen will, dann muß man int vermeiden und schlichtwegs alles als long deklarieren. Das hilft schon einigermaßen, obwohl es kein Allheilmittel ist, denn gerade bei Shifts usw. geht es von Compiler zu Compiler recht unterschiedlich zu: char C; long L; L = C << 2; geht auf manchen Systemen, aber nie auf allen. char C; long L; L = C; L = L << 2; geht auf allem, was ich bislang unter die Finger bekommen hab und kostet nicht mal zusätzlichen Code, bloß etwas zusätzliche Quelle. Die Krux bei C ist eben, daß die Erfinder von C so oberschlau gewesen sind, keine verläßlichen Datentypen in die Definition einzubauen. Das ist einer der vielen Geburtsfehler dieser Sprache, die man jetzt nicht mehr abschaffen kann. Leider. W.S.
W.S. schrieb: > Peter Dannegger schrieb: >> "int" und "long" sind bei Rechnungen, die eine bestimmte Bitbreite >> erfordern, Pfui-Bäh! > > Ach ja? > Na dann guck mal, was nach dem Preprozessor aus uint8_t, uint16_t usw. > übrig bleibt. Das ist derselbe Quark wie __IO, __I und __O, aus denen > ein schlichtes volatile nach dem Preprozessor wird. uint8_t soll ein "volatile" reinschmuggeln? Das ist jetzt nicht dein Ernst!
Ach ja?! Da die uint8_t und Konsorten alles typedefs sind, hat den Präprozessor da nichts zu interessieren... Und jede GCC-Version bringt eine passende stdint.h mit. In der steht dann der passende Datentyp definiert. Gruß Marius
W.S. schrieb: > char C; > long L; > L = C << 2; > geht auf manchen Systemen, aber nie auf allen. auf welchen soll das nicht gehen? char ist immer kleiner als int (default datentype). Wenn man jetzt C << 2 passt das also zwangsläufig in ein int rein. Damit muss auch die zuweisung nach long gehen. Das Hauptproblem ist aber das char weder signed noch unsigned ist dadurch ist das verhalten nicht identisch. Wer also char zum rechnen nimmt und sich über fehler wundert ist selber schuld.
Stefan Ernst schrieb: > Nö, es kann auch gleich groß sein. sicher? int ist mindestens 16bit - ich kenn kein System wo char 16bit ist.
W.S. schrieb: > Ach ja? > Na dann guck mal, was nach dem Preprozessor aus uint8_t, uint16_t usw. > übrig bleibt. Genau das gleiche, da der nix damit zu tun hat. > Ich halte überhaupt nichts von solchen Pseudo-Typen wie uint8_t und > Konsorten, weil das alles nur Unleserlichkeiten mit sich bringt, Was ist an uint8_t unleserich? Man erkennt sofort, daß es sich um einen vorzeichenlosen 8-Bit-Datentyp handelt. > die vom Preprozessor sowieso wieder gnadenlos aus der Quelle > herausgeschmissen werden. Sind Header auch unsinnig, weil sie durch den Preprozessor eh wieder ins C-File kopiert werden? > Die Krux bei C ist eben, daß die Erfinder von C so oberschlau gewesen > sind, keine verläßlichen Datentypen in die Definition einzubauen. Genau das wurde deshalb ja vor 13 Jahren mit dem uint*_t behoben, von dem du nichts hältst. > Das ist einer der vielen Geburtsfehler dieser Sprache, die man jetzt nicht > mehr abschaffen kann. Leider. Man hat Alternativen eingebaut. Wenn du die nicht verwendest, ist das nicht die Schuld der Sprache. Peter II schrieb: > Stefan Ernst schrieb: >> Nö, es kann auch gleich groß sein. > > sicher? int ist mindestens 16bit - ich kenn kein System wo char 16bit > ist. Das bedeutet nicht, daß es keins gibt. Nirgends steht, daß char nicht 16 Bit breit sein darf.
Rolf Magnus schrieb: > Das bedeutet nicht, daß es keins gibt. Nirgends steht, daß char nicht 16 > Bit breit sein darf. spielt aber keine rolle, denn wenn folgende referenz richtig ist char: Integer operations can be performed portably only for the range 0 ~ 127. dann ist der > char C; > long L; > L = C << 2; immer auf alles System gleich egal wie gross char ist. Wenn man werte > 127 nutzt, dann verläßt man eh den C standard.
Peter II schrieb: > sicher? Ja. Peter II schrieb: > int ist mindestens 16bit - ich kenn kein System wo char 16bit > ist. selten != nicht möglich Ich kann mich z.B. an einen Fall hier erinnern, wo die Verwirrung eines Fragers (ich glaube es ging um den Speicherverbrauch eines Arrays) schlicht darauf zurückzuführen war, dass auf seinem System (irgendein DSP) ein char 32 Bit hatte.
Peter II schrieb: > immer auf alles System gleich egal wie gross char ist. Wenn man werte > > 127 nutzt, dann verläßt man eh den C standard. Nein. In deinem Zitat steht "portably", das ist ja wohl was komplett anderes als "dann verläßt man eh den C standard". nicht portabel != nicht erlaubt
Stefan Ernst schrieb: > nicht portabel != nicht erlaubt nicht portabel == man kann sich auf das ergebniss nicht verlassen, also braucht man sich nicht wundern wenn ein anderes System anderes arbeitet.
OpenWatcom sollte 16-Bit Modus für DOS haben. Oder TurboC, auch als 16-Bitter.
Peter II schrieb: > Stefan Ernst schrieb: >> nicht portabel != nicht erlaubt > > nicht portabel == man kann sich auf das ergebniss nicht verlassen, also > braucht man sich nicht wundern wenn ein anderes System anderes arbeitet. Dann darf man deiner Meinung nach also auch einem 32-Bit int nichts größeres als 32767 zuweisen? Sorry, aber das ist doch jetzt echt Quatsch. Natürlich kann man sich auf das Ergebnis verlassen, nur eben nicht, wenn man den Source-Code auf einem anderen System mit anderen Rahmenbedingungen benutzt.
Stefan Ernst schrieb: > Dann darf man deiner Meinung nach also auch einem 32-Bit int nichts > größeres als 32767 zuweisen? richtig, denn dann ist es nicht mehr portabel. Und auf meinen Atmels sind die ints auch wirklich nur 16bit - dort kann ich also gar nicht mehr als 32767 zuweisen. Dafür gibt es ja jetzt uint32_t diesen kannst immer verwenden.
Peter II schrieb: > richtig, denn dann ist es nicht mehr portabel. Das ist dann aber nichts weiter, als deine persönliche Meinung, und hat nichts zu tun mit "dann verläßt man eh den C standard".
Stefan Ernst schrieb: >> richtig, denn dann ist es nicht mehr portabel. > Das ist dann aber nichts weiter, als deine persönliche Meinung, und hat > nichts zu tun mit "dann verläßt man eh den C standard". was hat das mit meiner meinung zu tun, wenn ich den gleichen code auf einen 8bit system und auf einem 32bit system übersetzten will? Dann kann ich mich nicht auf int=32bit verlassen. Wenn ich ein datentype mit 32bit brauche dann verwende ich uint_32 und weiss das es überall geht. Wenn du gerne int verwendest steht es dir doch frei es zu machen, musst dich dann nur nicht wundern wenn es auf einer andere Platform auf einmal nicht geht.
Peter II schrieb: > was hat das mit meiner meinung zu tun, Es geht darum, dass du behauptet hast, dass es nicht erlaubt sei. In Wirklichkeit ist es aber nur deine Meinung, dass man es nicht tun sollte.
Stefan Ernst schrieb: > Es geht darum, dass du behauptet hast, dass es nicht erlaubt sei. nein darum ging es NIE. wo habe ich behauptet das etwas nicht erlaubt ist? Das ganze fing damit an: > char C; > long L; > L = C << 2; > geht auf manchen Systemen, aber nie auf allen. ich habe geschrieben wenn man sich an den Standard (auch auch der compiler) hält, das das auf jeden System das gleiche liefert.
Peter II schrieb: > nein darum ging es NIE. wo habe ich behauptet das etwas nicht erlaubt > ist? hier: > Wenn man werte > > 127 nutzt, dann verläßt man eh den C standard. Peter II schrieb: > ich habe geschrieben wenn man sich an den Standard (auch auch der > compiler) hält, das das auf jeden System das gleiche liefert. Und genau das ist eben falsch. Deine Meinung darüber, was man tun oder lassen sollte, ist nun mal nicht "der C Standard".
Stefan Ernst schrieb: > hier: > >> Wenn man werte > >> 127 nutzt, dann verläßt man eh den C standard. und wo ist das jetzt falsch? Wenn man das macht ist es kein ISO C (C90) gültiger code. > > Peter II schrieb: >> ich habe geschrieben wenn man sich an den Standard (auch auch der >> compiler) hält, das das auf jeden System das gleiche liefert. > Und genau das ist eben falsch. Deine Meinung darüber, was man tun oder > lassen sollte, ist nun mal nicht "der C Standard". dann sagt doch mal bitte was daran falsch ist? Laut C90 ist das ergebniss auf alles C90 compilern gleich.
Peter II schrieb: > und wo ist das jetzt falsch? Wenn man das macht ist es kein ISO C (C90) > gültiger code. Dann sage mir doch bitte, wo im Standard steht, dass es verboten ist, einem 16-Bit char einen Wert >127 zuzuweisen.
Stefan Ernst schrieb: > Dann sage mir doch bitte, wo im Standard steht, dass es verboten ist, > einem 16-Bit char einen Wert >127 zuzuweisen. Hier: http://en.wikibooks.org/wiki/C_Programming/Reference_Tables Integer operations can be performed portably only for the range 0 ~ 127. Damit legt der Standard also fest das das verhalten nur für 0-127 definiert ist, alles was man sonst reinschreibt kann gehen muss aber nicht gehen.
Peter II schrieb: > Stefan Ernst schrieb: >> Dann sage mir doch bitte, wo im Standard steht, dass es verboten ist, >> einem 16-Bit char einen Wert >127 zuzuweisen. > > Hier: http://en.wikibooks.org/wiki/C_Programming/Reference_Tables > Integer operations can be performed portably only for the range 0 ~ 127. > > Damit legt der Standard also fest das das verhalten nur für 0-127 > definiert ist, alles was man sonst reinschreibt kann gehen muss aber > nicht gehen. Das ist aber nun nicht der C-Standard... Es ist bestenfalls eine "Side Note on Portability".
Johann L. schrieb: > Das ist aber nun nicht der C-Standard... > Es ist bestenfalls eine "Side Note on Portability". genau es legt fest, alles andere ist nicht definiert. Also nicht zum C Standard gehört. Damit ist klar das 0-127 der Standard ist.
Peter II schrieb: > Damit legt der Standard also fest das das verhalten nur für 0-127 > definiert ist nicht portable != nicht definiert Auf einem System mit char >8 Bit ist natürlich auch der definierte Zahlenbereich größer.
Stefan Ernst schrieb: > Auf einem System mit char >8 Bit ist natürlich auch der definierte > Zahlenbereich größer. dann zeig mir doch bitte mal ein dokument wo das steht?
egal wie groß ein bool ist, der definierte wertebereich ist auch immer gleich.
Peter II schrieb: > Stefan Ernst schrieb: >> hier: >> >>> Wenn man werte > >>> 127 nutzt, dann verläßt man eh den C standard. > > und wo ist das jetzt falsch? Wenn man das macht ist es kein ISO C (C90) > gültiger code. Das ist konformer ISO-C-Code. > Laut C90 ist das ergebniss auf alles C90 compilern gleich. Nein, ist es nicht. Peter II schrieb: > Johann L. schrieb: >> Das ist aber nun nicht der C-Standard... >> Es ist bestenfalls eine "Side Note on Portability". > > genau es legt fest, alles andere ist nicht definiert. Falsch. Es legt fest, was der C-Compiler mindestens können muß, nicht was das Programm höchstens nutzen darf. > Also nicht zum C Standard gehört. Falsch. Der sagt, daß char mindestens 8 Bit breit sein muß, aber auch jede beliebige größere Zahl an Bits haben darf. Und wenn mehr da ist, darf ein Programm das natürlich auch nutzen. > Damit ist klar das 0-127 der Standard ist. Falsch. Eine Schlußfolgerung aus falschen Annahmen. ISO C legt fest, welchen Bereich ein Compiler mindestens unterstützen muß, läßt ihm aber die Freiheit, auch einen größeren Bereich zu unterrstützen. Ein Compiler, der das tut, ist ISO-konform, genauso wie ein Programm, das das nutzt. Peter II schrieb: > Stefan Ernst schrieb: >> Auf einem System mit char >8 Bit ist natürlich auch der definierte >> Zahlenbereich größer. > > dann zeig mir doch bitte mal ein dokument wo das steht? Das steht in ISO/IEC 9899. Vielleicht solltest du statt irgendwelcher Wiki-Artikel mal das Dokument lesen, über das du hier diskutierst. Allerdings steht in diesem Artikel auch nicht, daß alles außerhalb des angegebenen Bereichs nicht ISO-konform sei, sondern nur, die Nutzung eines größeren Bereichs nicht auf jedem Compiler funktioniert.
Peter II schrieb: > Stefan Ernst schrieb: >> Auf einem System mit char >8 Bit ist natürlich auch der definierte >> Zahlenbereich größer. > > dann zeig mir doch bitte mal ein dokument wo das steht? C99:
1 | 5.2.4.2 Numerical limits |
2 | An implementation is required to document all the limits specified in this subclause, |
3 | which are specified in the headers <limits.h> and <float.h>. Additional limits are |
4 | specified in <stdint.h>. |
5 | |
6 | 5.2.4.2.1 Sizes of integer types <limits.h> |
7 | The values given below shall be replaced by constant expressions suitable for use in #if |
8 | preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX,the |
9 | following shall be replaced by expressions that have the same type as would an |
10 | expression that is an object of the corresponding type converted according to the integer |
11 | promotions. Their implementation-defined values shall be equal or greater in magnitude |
12 | (absolute value) to those shown, with the same sign. |
13 | —number of bits for smallest object that is not a bit-field (byte) |
14 | CHAR_BIT 8 |
15 | —minimum value for an object of type signed char |
16 | SCHAR_MIN -127 // −(2^7 − 1) |
17 | —maximum value for an object of type signed char |
18 | SCHAR_MAX +127 // 2^7 − 1 |
19 | —maximum value for an object of type unsigned char |
20 | UCHAR_MAX 255 // 2^8 − 1 |
21 | —minimum value for an object of type char |
22 | CHAR_MIN see below |
23 | —maximum value for an object of type char |
24 | CHAR_MAX see below |
25 | ... |
Wichtig hierbei: "implementation-defined" Der erlaubte Zahlenbereich wird also durch die jeweilige Implementation (also Compiler) definiert. Und: "equal or greater" Die gezeigten Werte sind also keine Soll-Werte, sondern Minimum-Werte.
>Stefan Ernst schrieb: >> Nö, es kann auch gleich groß sein. >sicher? int ist mindestens 16bit - ich kenn kein System wo char 16bit >ist. Programmier mal auf den C2000er DSPs von TI. z.B. den F2810 http://focus.ti.com/paramsearch/docs/parametricsearch.tsp?family=mcu§ionId=95&tabId=2216&familyId=1523 Dort ist alles 16 Byte breit. Es gibt keine Byte-Addressierung. Adresse 0 enthält 16 Bit. Adresse 1 enthält 16 Bit usw. Der Typ char ist dort auch 16 Bit breit, d.h. man verschwendet viel, wenn man mit ASCII arbeitet. 8 Bit breite Typen gibt es dort gar nicht. und sizeof(int) ist sizeof(char), beides ist 16 Bit. Wobei sizeof(int) = 1 ist, da ja nur eine Adresse belegt wird. Vielleicht solltest du einfach mal über den Tellerrand schauen und dich mit verschiedenen Architekturen beschäftigen.
PittyJ schrieb: > ielleicht solltest du einfach mal über den Tellerrand schauen und dich > mit verschiedenen Architekturen beschäftigen. es ging mir nur darum zu sagen, das wenn ich mich an die minimalen größe der Datentype halten, das es auf jedern Platform gleich funktioniert. Wenn ich etwas außerhalb davon verwende dann ist klar das es nicht überall funktioniert. Und wenn char 16bit gross ist (und man es auch nutzt), dann ist es doch gut. Aber ich weiss damit auch das ich damit nicht portabel bin. Wenn ich also ein Programm schreiben soll das auf einer möglichst alles Platformen arbeitet dann Verwende ich char nur von 0-127 (zum rechnen!). Dann weiss ich das es überall geht. Im thread ging es um einen unit Test der auf einem anderen System einen Fehler liefert, ich gehen davon aus das er ebend nicht sich an die minimale größe der Datentype gehalten hat, sonnst müsste es auf beiden system funktionieren.
stdint typen verwende ich natürlich! Na ich werde versuchen in Zukunft alles auf dem Target zu testen. Das das das beste ist war mir schon klar. lg
> sicher? int ist mindestens 16bit - ich kenn kein System wo char 16bit ist.
Char ist mindestens 8 bit, und auf den TMS320 ist er tatsächlich 16 bit,
und die sind nicht mal besonders exotisch.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.