[opensuse] strtof problem - what am I doing wrong?
Listmates,
I was comparing input handling between perl and c and I ran into a very weird
problem with the strtof function in c. What am I doing wrong? strtof doesn't
seem to be working like the man page shows. Here is my test bit of code:
#include
On Sunday 04 May 2008 03:19:29 David C. Rankin wrote:
Listmates,
I was comparing input handling between perl and c and I ran into a very weird problem with the strtof function in c. What am I doing wrong? strtof doesn't seem to be working like the man page shows. Here is my test bit of code: [...] The code compiles without error or warning with: "gcc -o prg/tmp src/tmp.c" Here is the bewildering output:
Well, no it doesn't. It says "implicit declaration of stdtof" If you read the man page for strtof it says Feature Test Macro Requirements for glibc (see feature_test_macros(7)): strtof(), strtold(): _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE; or cc -std=c99 So try gcc -std=c99 -o prg/tmp src/tmp.c Without that -std=c99, gcc simply doesn't know what strtof() is, and calls it incorrectly (it assumes it accepts an int as parameter and returns an integer, and generates assembly accordingly. You're unlucky you got bad data - the 'good' return value would have been a seg fault) Anders -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Anders Johansson wrote:
On Sunday 04 May 2008 03:19:29 David C. Rankin wrote:
Listmates, [...] The code compiles without error or warning with: "gcc -o prg/tmp src/tmp.c" Here is the bewildering output:
Well, no it doesn't. It says "implicit declaration of stdtof"
If you read the man page for strtof it says
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
strtof(), strtold(): _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE; or cc -std=c99
So try
gcc -std=c99 -o prg/tmp src/tmp.c
Without that -std=c99, gcc simply doesn't know what strtof() is, and calls it incorrectly (it assumes it accepts an int as parameter and returns an integer, and generates assembly accordingly. You're unlucky you got bad data - the 'good' return value would have been a seg fault)
Anders
Don't be so sure, I got a number of seg faults too ;-) Thanks. Now it makes sense. I read the man page 5 times over, but the -std=c99 never sank in. Googling gave hints in the discussions regarding GNU c, ASNI C and the c99 variant. The last time I was current and fluent with Fortan, C/C++ on both unix on Sun SPARC servers and Borland on (God forbid DOS 3.3) was 1995 when I left NASA in Houston to try the legal profession. (May 8, 1995 to be exact) It is amazing how much has changed and equally amazing how much has stayed the same in the past 13 years. Thanks for your continued help as I try and reconnect synapses and add a few new tools along the way. -- David C. Rankin, J.D., P.E. Rankin Law Firm, PLLC 510 Ochiltree Street Nacogdoches, Texas 75961 Telephone: (936) 715-9333 Facsimile: (936) 715-9339 www.rankinlawfirm.com -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
David C. Rankin wrote:
Anders Johansson wrote:
On Sunday 04 May 2008 03:19:29 David C. Rankin wrote:
Listmates, [...] The code compiles without error or warning with: "gcc -o prg/tmp src/tmp.c" Here is the bewildering output:
Well, no it doesn't. It says "implicit declaration of stdtof"
If you read the man page for strtof it says
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
strtof(), strtold(): _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE; or cc -std=c99
So try
gcc -std=c99 -o prg/tmp src/tmp.c
Without that -std=c99, gcc simply doesn't know what strtof() is, and calls it incorrectly (it assumes it accepts an int as parameter and returns an integer, and generates assembly accordingly. You're unlucky you got bad data - the 'good' return value would have been a seg fault)
Anders
Don't be so sure, I got a number of seg faults too ;-) Thanks. Now it makes sense. I read the man page 5 times over, but the -std=c99 never sank in. Googling gave hints in the discussions regarding GNU c, ASNI C and the c99 variant. The last time I was current and fluent with Fortan, C/C++ on both unix on Sun SPARC servers and Borland on (God forbid DOS 3.3) was 1995 when I left NASA in Houston to try the legal profession. (May 8, 1995 to be exact) It is amazing how much has changed and equally amazing how much has stayed the same in the past 13 years. Thanks for your continued help as I try and reconnect synapses and add a few new tools along the way.
I know how you feel. I'm finally getting around to learning C++ (solely because I believe that C++ + Qt is the best development environment for turning a series of rather complex boards game into a computer game). The last time I did any serious programming (other than writing shell scripts), ANSI C was still brand new. The K&R C book was still the standard reference & textbook. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Sun, 04 May 2008 01:26:42 -0400
Sam Clemens
I'm finally getting around to learning C++ (solely because I believe that C++ + Qt is the best development environment for turning a series of rather complex boards game into a computer game).
The last time I did any serious programming (other than writing shell scripts), ANSI C was still brand new. The K&R C book was still the standard reference & textbook.
There are a lot of good books on C++. (I started with the original K&R
C pre-ANSI which I still have). The problem with C++ and other OO
languages, is when you are coming from a procedural language like C,
you tend to write C programs in C++. To properly program in C++ (or in
Java for that matter), get a book on C++ style in addition to a good
C++ reference. There is also a C++ GUI programming with QT3. Also,
you'll find that there are some rules in C++ that differ from C. For
instance, in C a function declaration: int foo(); is legal for:
int foo(int arg1, int arg2, ..., int argn)
{
...
}
Where the elipses in this example are intended just to show arguments,
not varargs.
This is legal in standard C for backwards compatibility with K&R.
In C++, this is illegal. C++ requires full prototypes. A declaration
like "int foo();" in C++ means zero arguments. Additionally, "int
foo(void)" is not in the C++ standard, and may be rejected by the
compiler, though I've seen g++ and other compilers accept it.
Additionally, a C struct in C++ is a class with all members being
public, and has a default constructor and destructor.
C++ standard header files do not use the .h:
Additionally, the standard C header files are included in C++ as in
this example:
#include <iostream> // The C++ iostream header
#include <cstdio> // The C stdio.
int main()
{
std::cout << "Hello, world:-)\n"
printf("Hello, world:-)\n");
return 0;
}
You really should not mix C and C++ I/O in the same module, but there
are many cases where it may be necessary.
Remember that the main() function ALWAYS returns an int, never "void".
--
--
Jerry Feldman
Jerry Feldman wrote:
On Sun, 04 May 2008 01:26:42 -0400 Sam Clemens
wrote: I'm finally getting around to learning C++ (solely because I believe that C++ + Qt is the best development environment for turning a series of rather complex boards game into a computer game).
The last time I did any serious programming (other than writing shell scripts), ANSI C was still brand new. The K&R C book was still the standard reference & textbook.
There are a lot of good books on C++. (I started with the original K&R C pre-ANSI which I still have). The problem with C++ and other OO languages, is when you are coming from a procedural language like C, you tend to write C programs in C++. To properly program in C++ (or in Java for that matter), get a book on C++ style in addition to a good C++ reference. There is also a C++ GUI programming with QT3. Also, you'll find that there are some rules in C++ that differ from C. For instance, in C a function declaration: int foo(); is legal for: int foo(int arg1, int arg2, ..., int argn)
I have a couple. O'Reily's C++ book, the latest edition of Strastroup's latest book, and one from Dietel, Dietel and Associates (pretty good other than the annoying and childish cartoons of anthropomorphized bees --which have faces that are just plain...creepy looking -- like when they're out of public view, theyre involved in some sort of felonious conduct).
{ ... } Where the elipses in this example are intended just to show arguments, not varargs.
This is legal in standard C for backwards compatibility with K&R.
In C++, this is illegal. C++ requires full prototypes. A declaration like "int foo();" in C++ means zero arguments. Additionally, "int foo(void)" is not in the C++ standard, and may be rejected by the compiler, though I've seen g++ and other compilers accept it.
Yeah, I came across that with an older C++ book I read several years ago (at the time I purchased it in the early 1990's, I didn't have a computer of my own to learn on).
Additionally, a C struct in C++ is a class with all members being public, and has a default constructor and destructor.
That parallel is pretty obvious.
C++ standard header files do not use the .h:
Got caught with that one a couple times.
Additionally, the standard C header files are included in C++ as in this example:
#include <iostream> // The C++ iostream header #include <cstdio> // The C stdio. int main() { std::cout << "Hello, world:-)\n" printf("Hello, world:-)\n"); return 0; }
You really should not mix C and C++ I/O in the same module, but there are many cases where it may be necessary. Remember that the main() function ALWAYS returns an int, never "void".
In actuality, even with C, main() always returns an int. Otherwise, shell scripts looking for a return value would break. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Sun, 04 May 2008 15:31:15 -0400
Sam Clemens
I have a couple. O'Reily's C++ book, the latest edition of Strastroup's latest book, and one from Dietel, Dietel and Associates (pretty good other than the annoying and childish cartoons of anthropomorphized bees --which have faces that are just plain...creepy looking -- like when they're out of public view, theyre involved in some sort of felonious conduct).
I actually had Harvey Deitel as a professor for a graduate course once.
I also believe that the elevators in our building are controlled by the
program in Deitel's C++ book :-)
--
--
Jerry Feldman
Jerry Feldman wrote:
On Sun, 04 May 2008 15:31:15 -0400 Sam Clemens
wrote: I have a couple. O'Reily's C++ book, the latest edition of Strastroup's latest book, and one from Dietel, Dietel and Associates (pretty good other than the annoying and childish cartoons of anthropomorphized bees --which have faces that are just plain...creepy looking -- like when they're out of public view, theyre involved in some sort of felonious conduct).
I actually had Harvey Deitel as a professor for a graduate course once. I also believe that the elevators in our building are controlled by the program in Deitel's C++ book :-)
Other than the demonic-looking bees, I like the book. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Other than the demonic-looking bees, I like the book. Re: Deitel's C++ book. It's on my desk and I use it as a reference every once in a while. I actually got the book because I was to teach a C++ course at Northeastern University. However, I have found some interesting errors in the book. I don't recall where the errors are at the moment, but
On Sun, 04 May 2008 16:22:54 -0400
Sam Clemens
Jerry Feldman wrote:
On Sun, 04 May 2008 01:26:42 -0400 Sam Clemens
wrote: I'm finally getting around to learning C++ (solely because I believe that C++ + Qt is the best development environment for turning a series of rather complex boards game into a computer game).
The last time I did any serious programming (other than writing shell scripts), ANSI C was still brand new. The K&R C book was still the standard reference & textbook.
There are a lot of good books on C++. (I started with the original K&R C pre-ANSI which I still have). The problem with C++ and other OO languages, is when you are coming from a procedural language like C, you tend to write C programs in C++. To properly program in C++ (or in Java for that matter), get a book on C++ style in addition to a good C++ reference. There is also a C++ GUI programming with QT3. Also, you'll find that there are some rules in C++ that differ from C. For instance, in C a function declaration: int foo(); is legal for: int foo(int arg1, int arg2, ..., int argn) { ... } Where the elipses in this example are intended just to show arguments, not varargs.
This is legal in standard C for backwards compatibility with K&R.
In C++, this is illegal. C++ requires full prototypes. A declaration like "int foo();" in C++ means zero arguments. Additionally, "int foo(void)" is not in the C++ standard, and may be rejected by the compiler, though I've seen g++ and other compilers accept it.
Additionally, a C struct in C++ is a class with all members being public, and has a default constructor and destructor.
C++ standard header files do not use the .h: Additionally, the standard C header files are included in C++ as in this example:
#include <iostream> // The C++ iostream header #include <cstdio> // The C stdio. int main() { std::cout << "Hello, world:-)\n" printf("Hello, world:-)\n"); return 0; }
You really should not mix C and C++ I/O in the same module, but there are many cases where it may be necessary. Remember that the main() function ALWAYS returns an int, never "void".
Thanks Jerry, The early 90's is when I was in the thick of things with C++ and OOP with all it's inheritism and polymorphism and other constructs. I'm sure I still have a dozen or so 360k and 1.2M floppies full of old source code. I agree that module should either be in one or the other, but I see so many occasions in many applications where it is nothing but a blend. The hardest thing to get away from is C++ reliance on C functions. There is a lot of old code making use of various string, array, math, etc.. functions that people don't take the time to recode when they need the functionality in a C++ module. This captures it well: http://www.3111skyline.com/download/pictures/miscellaneous/software_engineer... -- David C. Rankin, J.D., P.E. Rankin Law Firm, PLLC 510 Ochiltree Street Nacogdoches, Texas 75961 Telephone: (936) 715-9333 Facsimile: (936) 715-9339 www.rankinlawfirm.com -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Sun, 04 May 2008 14:33:10 -0500
"David C. Rankin"
The early 90's is when I was in the thick of things with C++ and OOP with all it's inheritism and polymorphism and other constructs. I'm sure I still have a dozen or so 360k and 1.2M floppies full of old source code. I agree that module should either be in one or the other, but I see so many occasions in many applications where it is nothing but a blend. The hardest thing to get away from is C++ reliance on C functions. There is a lot of old code making use of various string, array, math, etc.. functions that people don't take the time to recode when they need the functionality in a C++ module.
This captures it well:
http://www.3111skyline.com/download/pictures/miscellaneous/software_engineer...
I think I first saw that cartoon back in the 1970s.
But, it tends to be accurate.
Back to C++, use C++ for most everything, and use C stuff only when
there is no C++ alternative. Use the STL also.
--
--
Jerry Feldman
On Sunday 04 May 2008 12:33, David C. Rankin wrote:
...
This captures it well:
http://www.3111skyline.com/download/pictures/miscellaneous/software_engineer...
A variation on a classic. Of course, if the customer doesn't know or can't say what they want, then the rest of us are really off the hook, aren't we? But the good news is that once we teach computers natural language understanding and how to program themselves, all these discrepancies will simply cease to occur!
-- David C. Rankin
RRS -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
Randall R Schulz wrote:
On Sunday 04 May 2008 12:33, David C. Rankin wrote:
...
This captures it well:
http://www.3111skyline.com/download/pictures/miscellaneous/software_engineer...
A variation on a classic.
Of course, if the customer doesn't know or can't say what they want, then the rest of us are really off the hook, aren't we?
Logically, yes. But unfortunately, ignorant customers are usually irrational customers, too, so they don't see it that way. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Sun, 04 May 2008 16:37:39 -0400
Sam Clemens
Randall R Schulz wrote:
On Sunday 04 May 2008 12:33, David C. Rankin wrote:
...
This captures it well:
http://www.3111skyline.com/download/pictures/miscellaneous/software_engineer...
A variation on a classic.
Of course, if the customer doesn't know or can't say what they want, then the rest of us are really off the hook, aren't we?
Logically, yes. But unfortunately, ignorant customers are usually irrational customers, too, so they don't see it that way.
I've seen many cases where the customer (or in my case product
marketing or sales) have an idea what they want, but are not able to
express it in a requirements document.
--
--
Jerry Feldman
David C. Rankin wrote:
Listmates,
I was comparing input handling between perl and c and I ran into a very weird problem with the strtof function in c. What am I doing wrong? strtof doesn't seem to be working like the man page shows. Here is my test bit of code:
#include
#include #include int main(int argc, char *argv[]) { char *endptr, *str, newstr[20]; float val, newval;
if (argc < 2) { fprintf(stderr, "Usage: %s number\n", argv[0]); exit(1); }
str = argv[1]; printf("\nstr = %s\nsizeof str = %d\nstrlen str = %d\n", str, sizeof(str), strlen(str));
strcpy(newstr,argv[1]); printf("\nnewstr = %s\nsizeof str = %d\nstrlen str = %d\n\n", newstr, sizeof(newstr), strlen(newstr));
val = strtof(str, &endptr);
endptr is uninitialized, so it's pointing at some random memory location.
newval = strtof(newstr, &endptr);
if (*endptr != '\0') printf("Additional characters after number: %s\n", endptr);
printf("str:\tstrtof of %s = %f\n", str, val); printf("newstr:\tstrtof of %s = %f\n\n", newstr, newval);
return(0); }
The code compiles without error or warning with: "gcc -o prg/tmp src/tmp.c" Here is the bewildering output:
20:03 Rankin-P35a~/linux/programming/c> ./prg/tmp 250.871
str = 250.871 sizeof str = 4 strlen str = 7
newstr = 250.871 sizeof str = 20 strlen str = 7
str: strtof of 250.871 = 1132125952.000000 newstr: strtof of 250.871 = 1132125952.000000
Obviously I must be missing something very simple, but I can't put my hands on it. Help?
-- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Saturday 03 May 2008 19:00, Sam Clemens wrote:
...
endptr is uninitialized, so it's pointing at some random memory location.
While it's true that the declaration of endptr leaves it uninitialized, that is not the problem. Strtof's second argument is **char. Strtof stores into this pointer (to a pointer to char) the pointer to the first character that was not used in translating the string into a float value. Calling strtof() with &endptr as its second argument is correct. Thus this is not the source of the problem. It is rather, as Anders states, that the compiler had not been told anything about strtof(), and called in the old, old C default way (as if it returns an int ... what else?).
...
Randall Schulz -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
David C. Rankin escribió:
int main(int argc, char *argv[]) { char *endptr, *str, newstr[20];
strcpy(newstr,argv[1]);
^^ ./a.out 23000000000000000000000000000000000000 *** stack smashing detected ***: ./a.out terminated classic buffer overflow.. do not use strcpy() it is evil. see https://buildsecurityin.us-cert.gov/daisy/bsi-rules/home/g1/848.html -- "Progress is possible only if we train ourselves to think about programs without thinking of them as pieces of executable code.” - Edsger W. Dijkstra Cristian Rodríguez R. Platform/OpenSUSE - Core Services SUSE LINUX Products GmbH Research & Development http://www.opensuse.org/
Cristian Rodríguez wrote:
David C. Rankin escribió:
int main(int argc, char *argv[]) { char *endptr, *str, newstr[20];
strcpy(newstr,argv[1]);
^^ ./a.out 23000000000000000000000000000000000000
*** stack smashing detected ***: ./a.out terminated ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I've never see that run-time error message. What compiler flags did you use to get THAT to be produced?
classic buffer overflow.. do not use strcpy() it is evil.
Yes. VERY evil. Use strncpy(char *dest, char *src, int maxlen).
see https://buildsecurityin.us-cert.gov/daisy/bsi-rules/home/g1/848.html
-- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
On Sunday 04 May 2008 11:46:12 Sam Clemens wrote:
Cristian Rodríguez wrote:
David C. Rankin escribió:
int main(int argc, char *argv[]) { char *endptr, *str, newstr[20];
strcpy(newstr,argv[1]);
^^ ./a.out 23000000000000000000000000000000000000
*** stack smashing detected ***: ./a.out terminated
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I've never see that run-time error message. What compiler flags did you use to get THAT to be produced?
-fstack-protector -ffortify=2 is also quite useful. At the cost of a bit of performance, it checks most of your boundaries for you Anders -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
"David C. Rankin"
[...] The code compiles without error or warning with: "gcc -o prg/tmp src/tmp.c" Here is the bewildering output:
Let me just comment on this one since others helped you already: Use gcc -O1 -Wall to get full warnings (without any optimisation, you will get less warnings, and by default you get no warnings). Output here is: t.c: In function ‘main’: t.c:23: warning: implicit declaration of function ‘strtof’ Andreas -- Andreas Jaeger, Director Platform / openSUSE, aj@suse.de SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126
On Sunday 2008-05-04 11:47, Andreas Jaeger wrote:
"David C. Rankin"
writes: [...] The code compiles without error or warning with: "gcc -o prg/tmp src/tmp.c" Here is the bewildering output:
Let me just comment on this one since others helped you already:
Use gcc -O1 -Wall to get full warnings (without any optimisation, you will get less warnings, and by default you get no warnings).
Output here is: t.c: In function ‘main’: t.c:23: warning: implicit declaration of function ‘strtof’
In the end, just use strtod :) -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org
participants (8)
-
Anders Johansson
-
Andreas Jaeger
-
Cristian Rodríguez
-
David C. Rankin
-
Jan Engelhardt
-
Jerry Feldman
-
Randall R Schulz
-
Sam Clemens