Hallo zusammen,
ich lese gerade eine Datei aus, welche aus dreistelligen HEX-Zahlen
getrennt durch ein Leerzeichen besteht.
Diese dreistelligen HEX-Zahlen beeinhalten IDs gewisser CAN-Botschaften
auf welche ich reagieren möchte.
Mein Problem tritt nun auf, wenn ich versuche diesen "String" in eine
long-Variable umzuwandeln. Dazu habe ich mich mal an einem
minimalistischen Beispiel versucht:
(Die Kommentare symbolisieren Alternativen, welche ebenfalls nicht
funktionierten)
1
//char temp[5] = {'0', '0', '0', '0', '\0'};
2
//char temp[] = "0000";
3
char*temp="0000";
4
longtest=(long)strtol(temp,0,16);
Das Ergebnis dieser zwei Zeilen lautet für mich unverständlicherweise
immer "2147483647".
Verwende ich stroul, ist das Ergebnis in der unsigned long Variable
übrigens auch wieder der maximal mögliche Wert...
stdlib.h ist als erstes in der main.c eingebunden.
Ich bin so langsam ziemlich ratlos und ärgere mich, dass ich schon seit
einigen Stunden an so einer "Kleinigkeit" hängen bleibe...
Vielen Dank abermals für eure Hilfe!
EDIT: Falls es wichtig sein sollte: Programmiert wird auf einem MSP430
mittels MSPGCC in CCSv6
Das Beispiel sieht so aus, als wenn es funktionieren sollte.
Das einzige auffällige Detail ist die Verwendung von 0 anstelle von
NULL.
Das eine ist ein Integer, das andere ein Zeiger (der ja hier erwartet
wird).
Allerdings meine ich, dass das nicht entscheidend ist.
Leider aber ist Dein Code unvollständig - bei Anfängern spielt manchmal
das Gesamtprogramm eine Rolle weil sie den Effekt von anderen Statements
falsch einschätzen. Poste bitte ein komplett kompilierbares und doch
minimales Programm.
Leider schreibst Du auch nicht auf welche Weise genau Du feststellst,
das MAX_LONG herauskommt - Anfänger benutzten manchmal unpassende
Methoden um Ergebnisse zu verifizieren oder interpretieren Ergebnisse
falsch.
Darüber hinaus - und wenn alles bisher gesagte, unzutreffend sein
sollte, ist das am wahrscheinlichsten - gibt es die Möglichkeit, dass
für die Benutzung von LONG eine andere Library gelinkt werden muss.
Einen ähnlichen Fall gibt es für Floating Point Libs beim AVR. Leider
kenne ich mich mit CCS nicht aus, aber die Dokumentation sollte das
klären - oder ein anderer freundlicher Mitleser.
Hallo,
danke für die Antwort. Natürlich kann ich dir auch ein einfaches,
komplettes Beispielprogramm anbieten:
1
#include"stdlib.h"
2
3
intmain(void)
4
{
5
char*temp="000A";
6
longtest=(long)strtol(temp,NULL,16);
7
if(test==0)
8
{
9
test++;
10
}
11
return0;
12
}
Die IF-Abfrage dient dabei nur als Abgriffspunkt zum Testen des Wertes
mittels Debugger. Die Variable test enthält danach den Wert 2147483647
und nicht wie ich eigentlich vermuten würde den Wert 10.
EDIT: Das selbe (Fehl-?)Verhalten bekomme ich auch bei Verwendung des
TI-Compilers...
#include "stdlib.h"
int main(void)
{
char temp[10];
strcpy(temp,"000A");
long test = (long)strtol(temp, NULL, 16);
if (test == 0)
{
test++;
}
return 0;
}
aendere das Programm mal so ab.
Hallo!
Damit bekomme ich folgende Warnungen
implicit declaration of function 'strcpy'
[-Wimplicit-function-declaration]incompatible implicit declaration of
built-in function 'strcpy' main.c
und ich kann mit dem Debugger nicht mehr in die Variable test
reinschauen irgendwie. Vermutlich funktioniert es aber immer noch nicht,
da in folgendem Code
1
#include"stdlib.h"
2
3
intmain(void)
4
{
5
chartemp[10];
6
strcpy(temp,"000A");
7
longtest=(long)strtol(temp,NULL,16);
8
if(test==0)
9
{
10
test++;
11
}
12
if(test==10)
13
{
14
test+=5;
15
}
16
return0;
17
18
}
Die Anweisung test += 5 nicht ausgeführt worden ist.
Ich bin jedoch über diesen Thread
Beitrag "Hex ASCII -> Int" auf die hexatoi von Timmo H.
aufmerksam geworden, welche ganz gut funktioniert.
Natürlich hilft mir das nur bedingt bei meinem ursprünglichen Problem,
aber damit kann ich jetzt erstmal weiter machen.
Wenn Ihr jedoch noch Ideen habt, warum diese Standard-Funktion nicht wie
gewünscht funktioniert, dann lasst es mich wissen ;-)
Roland M. schrieb:> implicit declaration of function 'strcpy'> [-Wimplicit-function-declaration]incompatible implicit declaration of> built-in function 'strcpy' main.c
Dann solltes du
#include <string.h>
noch einbinden.
tritt der Fehler immer noch auf. Es dürfte nicht an strcpy liegen, da
der Wert in der Variable temp korrekt ist. Das habe ich, genau wie auch
den Wert von test, mittels Debugger (JTAG) überprüft.
Du brauchst ihn nicht. Der Cast kann dir aber eine ev. Fehlermeldung vom
Compiler verhindern.
Man verwendet nie leichtfertig irgendwelche Casts! Casts sind Waffen und
man setzt sie nur ein, wenn es nicht anders geht. Aber auf keinen Fall
inflationär, in dem man alles niedercastet.
Roland M. schrieb:> tritt der Fehler immer noch auf. Es dürfte nicht an strcpy liegen, da> der Wert in der Variable temp korrekt ist. Das habe ich, genau wie auch> den Wert von test, mittels Debugger (JTAG) überprüft.
Variablen auf dem Stack sind für den Debugger manchmal ein Problem.
Nicht benutzte oder sinnlos erscheinende Variablen fliegen da gern mal
raus.
Teste das mal so:
1
volatilelongtest=0;
2
intmain(void)
3
{
4
test=strtol("000A",NULL,16);
Das volatile ist zwar überflüssig, trotzdem weiß keiner wie der Compiler
optimiert. Unter Windows bzw. LPC1769 und gcc geht alles riichtig. Kann
ja sein, dass die Implementierung von strtol bei dir keine hex-Werte
kann.
Also zur Basis 10 beträgt der Wert von test "1073692671". Dasselbe
passiert bei einer Konvertierung zur Basis 10 OHNE Cast.
Bei der endptr-Modifikation liegt temp an der Adresse 0x005BF0 und hat
den Value 0x005BF0 (stimmt das wirklich? Wenn ich mir den Wert Anzeigen
lassen, dann sehe ich "9x999A.U.M" und das macht ja Sinn).
endptr zeigt nach dem strtol-Aufruf auf die Adresse 0x5BF1, das ist das
x! Ist ja auch logisch, da ein x bei einer Konvertierung zur Basis 10
ziemlich sinnfrei ist.
Wenn ich die Basis nun wieder zu 16 ändere, dann zeigt endptr auf die
Adresse 0x5BF6 (das ist ein . (Punkte sind übrigens nicht anzeigbare
Zeichen wie z.B. 0x00 und Andere)). Auffällig ist für mich, dass die
Variable temp nach dem Aufruf aus den Werten "0x0......." besteht...?
EDIT: Auch mit einer globalen, volatilen Variable test besteht das
Problem weiterhin. Hierbei habe ich nochmal auf die Variable temp nach
Aufruf geachtet und diesmal war sie unangetastet, also "0x000A".
Vielleicht habe ich davor mit einen falschen Klick im Debugger den Wert
manipuliert (das passiert schonmal recht schnell leider). endptr zeigte
hierbei auf einen freien Bereich von temp ("also auf einen punkt").
EDIT2: Optimierungen sind komplett ausgeschaltet.
Um sicherzustellen, daß Dein Debugger Dich nicht anlügt:
Konvertiere den erhaltenen Wert in einen String, und lass Dir den (als
Hexdump des Speichers) vom Debugger anzeigen, da hat der Debugger es
beim Lügen etwas schwieriger.
Nun ja.
Der cast auf long ist, wie schon geschrieben, unnötig und unter
Umständen sogar kontraproduktiv.
In eine analoge Kategerie fallen auch die Versuche mit globalen oder
volatile Variablen. Der Code sollte auch ohne das funktionieren.
Allenfalls würde das, überraschende, funktionieren dieser Varianten auf
Fehler im Compiler hinweisen und das wäre recht unwahrscheinlich (wenn
auch nicht unmöglich). Und der Versuch von dem Benutzer temp zeigt, dass
der Code mit anderen Compilern und anderen CPUs funktioniert.
Ich nehme gewisse Unsicherheiten bei der Ablesung von Variablenwerten
wahr, die hier möglicherweise eine Rolle spielen. Allerdings habe ich
nicht den Eindruck, dass die hier entscheidend sind.
Ich würde an Deiner Stelle, Roland, zunächst einmal gründlich die
Dokumentation des Compilers bzw. der Libraries studieren und
insbesondere die Dokumentation zu Deiner Version von strtol. Lies bitte
nicht eine allgemeine Dokumentation im Internet oder sonstwo. Stelle
bitte sicher, dass Du definitiv die Dokumentation Deines Compilers und
Deiner Library liest. Es ist sehr wahrscheinlich, dass Du Die schon auf
Deiner Festplatte hast; dass sie bei der Installation des Compilers
mitinstalliert worden ist.
Die Zielrichtung dieser Lektüre ist die Klarstellung ob Deine Variante
von strtol oder ob sie nicht alle Basen unterstützt.
Ein Detail ist fällt mir allerdings noch ein: Probiere doch mal bitte,
ob ein String wie "0" (also nicht "0000") auch nicht korrekt umgewandelt
wird.
Hallo zusammen!
@Bitflüsterer:
Auch dieses Programm:
1
#include"stdlib.h"
2
#include"string.h"
3
4
volatilelongtest=0;
5
6
intmain(void)
7
{
8
chartemp[10];
9
strcpy(temp,"0");
10
char*endptr;
11
test=strtol(temp,&endptr,10);
12
if(test==0)
13
{
14
test++;
15
}
16
if(test==10)
17
{
18
test+=5;
19
}
20
return0;
21
}
funktioniert leider nicht. Das Ergebnis ist wieder falsch (1073692671).
Der endptr zeigt auf die zweite Stelle in temp - also auf das ende des
strings. Dasselbe gilt für den Aufruf zur Basis 16.
@Alle:
Wie gesagt habe ich schon auf eine andere Funktion zurückgegriffen,
weshalb die Priorität dieses Problems ein wenig gesunken ist für mich.
Dennoch frage ich mich natürlich auch, warum das diese Funktion nicht
funktioniert. Ich denke schon, dass ich sehr wohl in der Lage bin
mittels des Debuggers gewisse Werte aus Variablen auslesen zu können,
daher glaubt mir bitte, wenn ich schreibe welche Variable welchen Wert
hat.
Vielleicht schaue ich mir mal die Dokumentation meines benutzten
Compilers an, aber auch da sehe ich eher schwarz. Zum Einen habe ich
zwei Compiler getestet (MSPGCC und den von TI) und bei beiden kam es zu
Problemen. Zum Anderen glaube ich, dass ein solches Dokument recht
schwer verdauliche Kost für mich sein dürfte...
EDIT: Beim MSPGCC bin ich auf Folgendes Dokument gestoßen, welches mir
den Eindruck vermittelt, dass die Funktion in vollem Umfang zur
Verfügung stehen muss (sonst würde wohl kaum auf die Standard-C-Doku
verwiesen würden): http://mspgcc.sourceforge.net/manual/x1109.html
Roland M. schrieb:> Ich denke schon, dass ich sehr wohl in der Lage bin mittels des> Debuggers gewisse Werte aus Variablen auslesen zu können, daher glaubt> mir bitte, wenn ich schreibe welche Variable welchen Wert hat.
Selig sind die, die ihren Werkzeugen blind Vertrauen schenken.
Zum eigentlichen Problem: Der Quelltext der Funktion sollte bei den
Runtime-Library-Sourcen dabei sein, den kannst Du Dir ja mal zu Gemüte
führen.
In \ti\ccsv6\tools\compiler\msp430_4.3.4\lib\mklib.c ist ebenfalls ein
Aufruf von strtol zu verzeichnen.
Außerdem finde ich die folgende Datei in
\ti\ccsv6\tools\compiler\msp430_4.3.4\lib\src\strtol.c, welche ich euch
mal hochlade mit diesem Post.
Ich denke mal die angehängte Datei ist entscheidend und zumindest für
mich sieht es nach einer vollständigen Implementierung aus...
> Ich denke mal die angehängte Datei ist entscheidend und> zumindest für mich sieht es nach einer vollständigen> Implementierung aus...
Das lässt sich ja einfach feststellen. Und auch die Frage, ob das
tatsächlich der Code der Funktion ist, die ausgeführt wird.
Füge diese Funktionsdefinition in ein Testprogramm ein und steppe sie
durch. Dann siehst Du ja was geschieht.
Benenne die Funktion am bestem um, um jeden Zweifel zu beseitigen.
Evtl. musst Du das _CODE_ACCESS-Attribut entfernen - das kann ich nicht
beurteilen.
> Zum Einen habe ich zwei Compiler getestet (MSPGCC und den> von TI) und bei beiden kam es zu Problemen.
Bei beiden Compilern das identische Problem? Das halte ich für sehr
unwahrscheinlich. Das liegt an was anderem.
Roland M. schrieb:> Vielleicht schaue ich mir mal die Dokumentation meines benutzten> Compilers an, aber auch da sehe ich eher schwarz. Zum Einen habe ich> zwei Compiler getestet (MSPGCC und den von TI) und bei beiden kam es zu> Problemen. Zum Anderen glaube ich, dass ein solches Dokument recht> schwer verdauliche Kost für mich sein dürfte...
Da Du als Rückgabewert LONG_MAX bekommst, tritt bei der Umwandlung
offenbar ein Range-Error auf.
Was passiert denn mit Deinem Compiler, wenn Du mal <errno.h> mit in
Deinen Code einbindest und die Variable "errno" auf 0 setzt, bevor Du
strtol aufrufst?
Einer kleiner Arduino-Code für ein Testprogramm mit Errorhandling für
die strtol Funktion wäre sowas wie:
1
#include <errno.h>
2
#include <limits.h>
3
void setup() {
4
Serial.begin(9600);
5
char *n = "0CA000AB";
6
char *p;
7
long test;
8
errno = 0;
9
test = strtol(n, &p, 16);
10
11
if (p == n)
12
Serial.println("No digits found.\n");
13
else if ((test == LONG_MIN || test == LONG_MAX) && errno == ERANGE)
14
Serial.println("Value out of range.\n");
15
else
16
{
17
Serial.print("Value is ");
18
Serial.println(test);
19
}
20
}
21
22
void loop() {}
Vielleicht kannst Du dieses strtol()-Errorhandling ja mal auf Deinen
Compiler umsetzen.
Doch, gerade nochmal getestet.
GNU v4.9.1 und TI v4.3.4
Um die Funktion aus der Datei in mein Programm einzubauen und mir die
Unterfunktionsaufrufe rauszusuchen, habe ich im Moment keine Zeit für.
Ich denke aber, dass du Recht hast, und der Fehler irgendwo anders
liegt. Ich frage mich nur wo das sein könnte, dann an meinem kleinem
Testprogramm ist ja nicht viel Spielraum um etwas falsch machen zu
können...
@Jürgen S.:
Nach diesem Umbau lande ich im Else-Case (wo eigentlich alles in Ordnung
sein sollte), aber meine test-Variable hat wieder einen falschen Wert
(1073692671).
Den Wert von errno kann ich euch leider nicht mitteilen, da der Debugger
hier sagt: cannot load from non-primitive location
Roland M. schrieb:> Doch, gerade nochmal getestet.>> GNU v4.9.1 und TI v4.3.4>> Um die Funktion aus der Datei in mein Programm einzubauen und mir die> Unterfunktionsaufrufe rauszusuchen, habe ich im Moment keine Zeit für.> Ich denke aber, dass du Recht hast, und der Fehler irgendwo anders> liegt. Ich frage mich nur wo das sein könnte, dann an meinem kleinem> Testprogramm ist ja nicht viel Spielraum um etwas falsch machen zu> können...
Ich tippe auch auf den Debugger bzw. Optimierung.
Es scheint nicht klar zu sein, wo der Wert von "test" zu finden ist.
Manchmal hilft hier den Disassembler zu verwenden und die einzelnen
Assemblerbefehle durch zu steppen. Dann bist du dir sicher, wo der
Rückgabewert von srttol() hingeschrieben wird (wenn überhaupt).
Roland M. schrieb:> @Jürgen S.:> Nach diesem Umbau lande ich im Else-Case (wo eigentlich alles in Ordnung> sein sollte), aber meine test-Variable hat wieder einen falschen Wert> (1073692671).>
Im Else-Case ist "test" schon wieder ungültig und eventuell
überschrieben.
Setze den Breakpoint auf das erste "if" und schau was in "test" steht.
Roland M. schrieb:> Den Wert von errno kann ich euch leider nicht mitteilen, da der Debugger> hier sagt: cannot load from non-primitive location
Einfach auf eine andere Variable kopieren.
Hast du das ganze auch mal im Simulator getestet anstatt im JTag
debugger?
> ... die Unterfunktionsaufrufe rauszusuchen, ...
Zu welchem Zweck würdest Du das tun wollen?
> Ich frage mich nur wo das sein könnte, dann an meinem> kleinem Testprogramm ist ja nicht viel Spielraum um> etwas falsch machen zu können...
Das ist im wesentlichen beantwortet worden:
1. Bedienungsfehler des Debuggers
2. Bedienungsfehler des Compilers.
Mehr können wir mangels tieferer Informationen und wegen Deines
Ausschlusses von Punkt 1. nicht sagen.
Das der Compiler schuld ist, d.h. dass zwei unterschiedliche Compiler
das selbe Fehlverhalten zeigen ohne das der Programmierer dafür
verantwortlich ist, ist ungefähr so wahrscheinlich wie ein Lotto-Gewinn.
Nochmals Hallo!
errno hat direkt nach dem Aufruf einen Wert von "0".
test hat direkt nach dem Aufruf einen Wert von "1073692671".
Siehe folgendes Programm:
Was mir dabei jedoch ins Auge gefallen ist, ist die folgende Warnung für
die mit (X) markierte Zeile:
this decimal constant is unsigned only in ISO C90 main.c
Ich weiß nicht, wie es zu einem Bedienungsfehler kommen sollte? Ich
benutze dieselbe IDE mit denselben Einstellungen und derselben Hardware,
welche ich auch für mein richtiges Projekt OHNE Probleme einsetze.
Roland M. schrieb:> #define LONG_MAX 2147483647> #define LONG_MIN -2147483648
Schreib das mal so:
#define LONG_MAX 2147483647L
#define LONG_MIN -2147483648L
Roland M. schrieb:> Nochmals Hallo!>> errno hat direkt nach dem Aufruf einen Wert von "0".> test hat direkt nach dem Aufruf einen Wert von "1073692671".
"direkt nach dem Aufruf" ?
Wo sitzt der Breakpoint?
Wieso ist "test" nicht 0 (direkt nach dem Aufruf) ???
> this decimal constant is unsigned only in ISO C90 main.c
Ersetze
1
#define LONG_MAX 2147483647
2
#define LONG_MIN -2147483648
durch
1
#include<limits.h>
Wozu noch eine eigene Präprozessor-Definition?
> Ich weiß nicht, wie es zu einem Bedienungsfehler kommen sollte?
Ja eben. Ich behaupte ja nicht, dass Du es weißt, sondern das Du es
nicht weißt.
> Ich benutze dieselbe IDE mit denselben Einstellungen und> derselben Hardware, welche ich auch für mein richtiges> Projekt OHNE Probleme einsetze
Moment mal. In Deinem RICHTIGEN Projekt tritt das Problem nicht auf?
Das hatte ich anders verstanden.
Der Breakpoint sitzt auf dem Funktionsaufruf von strtol (7 Zeilen über
der mit (X) markierten Zeile). Danach mache ich drei Prozedurschritte
mit dem Debugger. Mit dem ersten Schritt wird strtol ausgeführt. Mit dem
zweiten wird errno ausgelesen (0). Mit dem dritten wird test in kopie3
gesichert mit dem Wert von 1073692671.
> Wieso ist "test" nicht 0 (direkt nach dem Aufruf) ???
Wieso sollte es?
> #define LONG_MAX 2147483647L> #define LONG_MIN -2147483648L
Auch dies bringt nichts, die Warnung bleibt bestehen.
EDIT:
> Moment mal. In Deinem RICHTIGEN Projekt tritt das Problem nicht auf?> Das hatte ich anders verstanden.
Doch, da trat das Problem auch auf. Daher bin ich auf (s.o.) hexatoi
umgestiegen, welches ohne Probleme läuft. Da das strtol auch in meinem
kleinem Testprogramm nicht funktioniert, mache ich mir kenie Sorgen,
dass in meinem richtigen Projekt irgendetwas schief läuft...
EDIT2:
Das Inkludieren von limits.h hat die Warnung beseitigt.
Hallo,
bei mir (Atmel Studio 6.2) funktioniert alles. Wenn ich im folgenden auf
die while Schleife einen Breakpoint setze, gibt der Debugger dort für
die Variable test eine 10 zurück.
1
#include"stdlib.h"
2
#include<avr/io.h>
3
4
intmain(void)
5
{
6
char*temp="000A";
7
longtest=(long)strtol(temp,NULL,16);
8
if(test==0)
9
{
10
test++;
11
}
12
13
while(10==test)PORTB^=0x01;
14
15
return0;
16
}
Ohne die while-Schleife optimiert der Compiler (Einstellung -Os)
hingegen die Variable test quasi weg. "Quasi" heißt, dass zwar die
Funktion strtol aufgerufen wird, deren Ergebnis aber nirgendwo mehr
abgelegt wird. Wozu auch - Wird ja im folgenden nicht mehr gebraucht.
Das ändert sich hier durch die while-Schleife.
Die oben genannte Vermutung des fahrlässigen Gebrauchs des Debuggers ist
also offensichtlich zutreffend.
> Da das strtol auch in meinem kleinem Testprogramm nicht> funktioniert, mache ich mir kenie Sorgen,> dass in meinem richtigen Projekt irgendetwas schief läuft...
Daraus, daß ein Problem in zwei verschiedenen Programmen auftritt und
nicht nur in einem von beiden, schliesst Du daraus das Du in dem einen
von den beiden keinen Fehler machst?
Das ist hübsch. :-) Nur logisch ist es nicht.
Detlev T. schrieb:> Ohne die while-Schleife optimiert der Compiler (Einstellung -Os)> hingegen die Variable test quasi weg. "Quasi" heißt, dass zwar die> Funktion strtol aufgerufen wird, deren Ergebnis aber nirgendwo mehr> abgelegt wird. Wozu auch - Wird ja im folgenden nicht mehr gebraucht.> Das ändert sich hier durch die while-Schleife.>> Die oben genannte Vermutung des fahrlässigen Gebrauchs des Debuggers ist> also offensichtlich zutreffend.
Thanx!
Bitflüsterer schrieb:>> Da das strtol auch in meinem kleinem Testprogramm nicht>> funktioniert, mache ich mir kenie Sorgen,>> dass in meinem richtigen Projekt irgendetwas schief läuft...>> Daraus, daß ein Problem in zwei verschiedenen Programmen auftritt und> nicht nur in einem von beiden, schliesst Du daraus das Du in dem einen> von den beiden keinen Fehler machst?>> Das ist hübsch. :-) Nur logisch ist es nicht.
Zumindest kann ich damit ausschließen dass irgendein Laufzeitfehler
auftritt, der den Aufruf dieser Funktion stört. Natürlich ist das kein
Beleg für die Fehlerfreiheit des restlichen Projekts ;-)
> Ohne die while-Schleife optimiert der Compiler (Einstellung -Os)> hingegen die Variable test quasi weg. "Quasi" heißt, dass zwar die> Funktion strtol aufgerufen wird, deren Ergebnis aber nirgendwo mehr> abgelegt wird. Wozu auch - Wird ja im folgenden nicht mehr gebraucht.> Das ändert sich hier durch die while-Schleife.
Erstens sind alle meine Optimierungen ausgeschaltet (und ich meine
wirklich alle). Zweitens habe ich dazu die IF-Anweisungen eingefügt. Es
kann also wirklich nicht am Optimierer liegen (diesmal - ich hatte
schonmal ein ähnliches Problem).
> Die oben genannte Vermutung des fahrlässigen Gebrauchs des Debuggers ist> also offensichtlich zutreffend.
Das sehe ich leider anders. Nur weil ihr den Fehler genau so wenig
finden könnt wie ich, heißt das doch nicht, dass ich auf einmal keinen
Debugger mehr bedienen kann?
Ich kann gerne eine while-Schleife für dich dahinter setzen, aber das
wird das Ergebnis nicht ändern. Soll ich es dennoch für dich versuchen?
Roland M. schrieb:> Ich kann gerne eine while-Schleife für dich dahinter setzen, aber das> wird das Ergebnis nicht ändern. Soll ich es dennoch für dich versuchen?
Das Ergebnis würde mich interessieren...
Roland M. schrieb:> Zweitens habe ich dazu die IF-Anweisungen eingefügt
Alles was in und nach dem IF passiert hat keine Auswirkung nach Aussen
und kann daher weggelassen werden.
test wird in deinem Programm überhaupt nicht gebraucht.
Dirk B. schrieb:> Roland M. schrieb:>> Zweitens habe ich dazu die IF-Anweisungen eingefügt>> Alles was in und nach dem IF passiert hat keine Auswirkung nach Aussen> und kann daher weggelassen werden.>> test wird in deinem Programm überhaupt nicht gebraucht.
Das ändert immer noch nichts daran, dass die Optimierungen ausgeschaltet
sind. Und zwar alle.
Folgender Aufbau für Dich, Daniel V. (danvet):
Hallo nocheinmal,
mit ausgeschalteter Optimierung (-O0) und Breakpoint auf dem return gibt
mein Debugger für test als Ergebnis eine 10 im folgenden Programm. Bei
Veränderung von temp ändert sich dieser Wert entsprechend.
1
#include"stdlib.h"
2
3
intmain(void)
4
{
5
char*temp="000A";
6
7
longtest=(long)strtol(temp,NULL,16);
8
if(test==0)
9
{
10
test++;
11
}
12
13
return0;
14
}
Roland M. schrieb:> Erstens sind alle meine Optimierungen ausgeschaltet (und ich meine> wirklich alle).
Das bezweifle ich nach meinem Test aber doch sehr.
Daniel V. schrieb:> Roland M. schrieb:>>> Gibt es noch weitere Ideen?> Ja, kannst du bitte das hier:>> SchnippSchnapp>> mal weglassen.> Was passiert dann.
Dasselbe. Sofort nach dem Aufruf von strtol, wechselt der Wert von test
von 0 auf 1073692671. Danach geht es in die zweite while-Schleife.
>> Erstens sind alle meine Optimierungen ausgeschaltet (und ich meine>> wirklich alle).>Das bezweifle ich nach meinem Test aber doch sehr.
Hierzu hänge ich Dir gerne noch einen kleinen Beweisscreenshot an...
Roland M. schrieb:> Dasselbe. Sofort nach dem Aufruf von strtol, wechselt der Wert von test> von 0 auf 1073692671. Danach geht es in die zweite while-Schleife.
Na dann belassen wir es dabei, dass dein strtol() kaputt ist.
Klingt komisch... Aber wenn es sonst keine weiteren Ideen mehr gibt,
dann muss ich das wohl so hinnehmen...
Jedenfalls liegt es ganz sicher nicht an einer Optimierung.
Da der Compiler wohl kaum fehlerhaft sein wird, muss es wohl an mir
liegen. Allerdings könnt weder Ihr noch Ich mir sagen, was ich wohl
falsch mache...
Daniel V. schrieb:> Roland M. schrieb:>> Dasselbe. Sofort nach dem Aufruf von strtol, wechselt der Wert von test>> von 0 auf 1073692671. Danach geht es in die zweite while-Schleife.>> Na dann belassen wir es dabei, dass dein strtol() kaputt ist.
Ist aber trotzdem unbefriedigend. strtol hat zwar ein paar
Kleinigkeiten, die berücksichtigt werden wollen, aber die
Grundimplementierung ist eigentlich so einfach (und vor allen Dingen ist
sie ja seit Jahrzehnten bekannt), dass die Wahrscheinlichkeit dafür
recht gering ist.
Allerdings: Ich kann auch keine Erklärung anbieten. Ich denke jetzt wäre
der Zeitpunkt erreicht, an dem nur noch der Gang runter zum
Assemblercode bleibt um nachzusehen, wie das Ergebnis zustande kommt.
Morgen vielleicht... Für heute habe ich die Nase doch recht voll.
Ich wollte euch hiermit nichts vorwerfen. Ich habe durchweg gute
Erfahrungen mit diesem Forum hier und den Menschen, die sich hier
rumtreiben und anderen helfen, gesammelt. Sei es die Reaktionszeit, die
Fachlichkeit oder der Humor. Aber irgendwie kommen wir hier dennoch
nicht weiter...
Roland M. schrieb:> Hierzu hänge ich Dir gerne noch einen kleinen Beweisscreenshot an..
Ich kenne diese IDE nicht. Was steht denn in der Auswahlbox für die
Optimierung, wenn sie nicht leer ist? Wenn die IDE das so für den
Compiler umsetzt:
-O<Inhalt Auswahlbox>
Dann entspricht diese Einstellung nämlich dem Optimierungslevel 1. Also
hier vielleicht explizit einmal ein 0 eintragen.
None -O0
Optimize -O1
Optimize More -O2
Optimize Most -O3
Allerdings habe ich auch schon die Erfahrung gesammelt, dass die
Checkboxen zur Optimierung selbst bei "None -O0" noch greifen und
explizit ausgestellt werden müssen.
Ich habe es nun nochmals mit der Einstellung "None -O0" getestet. Es hat
sich nichts verändert.
Eine Alternative (oder ein Schritt vor dem "Assembler-Studium") wäre
vielleicht die oben von mir schon vorgeschlagene.
Den Quellcode von strtol nehmen und mal austesten. Ich habe mal den
Code, wie ich ihn testen würde, angehängt. (Man braucht da keine
Unterfunktion rauszusuchen).
Was die Optimierung betrifft, halte ich den Compileraufruf für
maßgebend. Bei einer IDE weiß man nie, was die sich selbst denkt. Poste
doch mal den Aufruf selbst.