| | |
what's with gcc?
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
The following code finds the square root of a number, it runs fine unless you compile with MinGW gcc:
The problem is if compiled with compilers other than gcc (I have tested it with lcc, visual C++ and borland C++) it reaches "finished" but for gcc it never gets out of the loop. Try to find sqrt of 5, 7 and you will see what I mean. I know about the issues involving comparison of double datatypes, but in this particular case it is guaranteed that x1 will stop changing after certain iterations.
Now for the most interesting part. Uncomment the printf statement within the loop. And you will see everything works fine. I got no clue what's happening inside gcc.
I want to know if anyone's gcc(MinGW) compiler is also behaving the same or not.
C++ Syntax (Toggle Plain Text)
#include<stdio.h> #include<stdlib.h> int main(void) { double x0,x1,a; int i; x1 = 1; x0 = 0; printf("\nFind square root of: "); scanf("%lf",&a); for(i = 0; x0 != x1; ++i) { x0 = x1; x1 = .5 * (x1 + a / x1); // printf("\nIteration %d - converging to %lf - prev value %lf",i,x1,x0); } printf("Finished"); return 0; }
The problem is if compiled with compilers other than gcc (I have tested it with lcc, visual C++ and borland C++) it reaches "finished" but for gcc it never gets out of the loop. Try to find sqrt of 5, 7 and you will see what I mean. I know about the issues involving comparison of double datatypes, but in this particular case it is guaranteed that x1 will stop changing after certain iterations.
Now for the most interesting part. Uncomment the printf statement within the loop. And you will see everything works fine. I got no clue what's happening inside gcc.
I want to know if anyone's gcc(MinGW) compiler is also behaving the same or not.
"He who mixes with people and endures the harm they do is better than he who does not mix and endures." (Tirmidhi)
> I know about the issues involving comparison of double datatypes
"This is a hole, and I know I'm lying at the bottom of it."
What exactly were you expecting to happen?
If you know about the issues, why didn't you code around them and test on each compiler?
> The problem is if compiled with compilers other than gcc (I have tested it with lcc, visual C++ and borland C++
Proving that your code has undefined behaviour.
> but in this particular case it is guaranteed that x1 will stop changing after certain iterations.
Just because the printf outputs "1.234" and "1.234" does not mean the equivalent numeric test for inequality will fail. Printing things to only 6 digits of precision when doubles have 15 digits of precision is going to entail a certain amount of rounding.
> Uncomment the printf statement within the loop. And you will see everything works fine.
Try printing out the value of i at the end of the loop.
Without printf slowing it down, it's probably executing many 1000's more iterations. Which might mean it eventually stumbles upon convergence.
Adding a final "\n" to your printf would be a good idea as well.
"This is a hole, and I know I'm lying at the bottom of it."
What exactly were you expecting to happen?
If you know about the issues, why didn't you code around them and test on each compiler?
> The problem is if compiled with compilers other than gcc (I have tested it with lcc, visual C++ and borland C++
Proving that your code has undefined behaviour.
> but in this particular case it is guaranteed that x1 will stop changing after certain iterations.
Just because the printf outputs "1.234" and "1.234" does not mean the equivalent numeric test for inequality will fail. Printing things to only 6 digits of precision when doubles have 15 digits of precision is going to entail a certain amount of rounding.
> Uncomment the printf statement within the loop. And you will see everything works fine.
Try printing out the value of i at the end of the loop.
Without printf slowing it down, it's probably executing many 1000's more iterations. Which might mean it eventually stumbles upon convergence.
Adding a final "\n" to your printf would be a good idea as well.
C++ Syntax (Toggle Plain Text)
#include <stdio.h> #include <stdlib.h> int main(void) { float x0,x1,a; printf("\nFind square root of: "); scanf("%f",&a); float t = 10; int i; for(i = 0; i<100; i++) { t = t - ((t*t - a)/(2*t)); printf("\nIteration %f ",t); } printf("Finished\n"); getchar(); getchar(); //return 0; }
One more thing, I would use newton's formula for rapid convergence as shown above. It also eliminates the comparison stumbling block.
*Voted best profile in the world*
•
•
•
•
"This is a hole, and I know I'm lying at the bottom of it."
What exactly were you expecting to happen?
If you know about the issues, why didn't you code around them and test on each compiler?
•
•
•
•
Proving that your code has undefined behaviour.
•
•
•
•
Just because the printf outputs "1.234" and "1.234" does not mean the equivalent numeric test for inequality will fail. Printing things to only 6 digits of precision when doubles have 15 digits of precision is going to entail a certain amount of rounding.
•
•
•
•
Try printing out the value of i at the end of the loop.
•
•
•
•
Adding a final "\n" to your printf would be a good idea as well.
•
•
•
•
works ok with Dev-C++ (version 4.9.9.2 which uses gcc),
I still can't explain the way my program is behaving. Why printing inside the loop makes the program work and not printing inside the loop takes it into an infinite loop(when compiled using MinGW gcc version 3.4.2).
"He who mixes with people and endures the harm they do is better than he who does not mix and endures." (Tirmidhi)
> I said so because some of you might jump into the conclusion that checking for
> inequality between two double datatypes is what's wrong with my code.
http://docs.sun.com/source/806-3568/ncg_goldberg.html
http://c-faq.com/fp/fpequal.html
Just because you believe that it "isn't a problem for me" doesn't mean that it isn't a problem. The fact that it works for you sometimes, with some compilers doesn't mean that there isn't a problem.
> it could very well be for a bug with the version of gcc I have.
Statements like this require huge amounts of proof - you don't have that.
Did you disassemble all the generated code to find out what the compiler really did?
Besides, if you did, you should have visited
http://www.mingw.org/bugs.shtml
Not to mention
Read
http://www.mingw.org/mingwfaq.shtml
"MinGW uses the Microsoft runtime libraries, distributed with the Windows operating system"
It does not use the standard GNU LibC implementation, but inherits all the bugs and features of the host libraries.
Maybe by feeding printf() bogus format sequences it's corrupting the stack and the rest of your local variables into the bargain.
Do you still see a problem when you use correct printf format controls?
> Do you have the 3.4.2 version of MinGW? Did you try my code with it? If you did, did you see the weird behaviour I mentioned above?
No, No and No.
Generally speaking, I try and sort out the obvious deficiencies (such as undefined or suspicious behavior) before actually bothering to try and run code myself.
> Adding a '\n' to my printf doesn't make the weird behaviour go away, This advice of
> yours is not only childish but also completely irrelevant to the issue at hand.
Here's chapter and verse from the C89 standard.
Again, all this "works for me with the foo and bar compilers" doesn't make your code bug free, or free from different implementation specific behaviours.
And how would you know whether it was an issue or not, since you have yet to figure out the answer to the question?
> inequality between two double datatypes is what's wrong with my code.
http://docs.sun.com/source/806-3568/ncg_goldberg.html
http://c-faq.com/fp/fpequal.html
Just because you believe that it "isn't a problem for me" doesn't mean that it isn't a problem. The fact that it works for you sometimes, with some compilers doesn't mean that there isn't a problem.
> it could very well be for a bug with the version of gcc I have.
Statements like this require huge amounts of proof - you don't have that.
Did you disassemble all the generated code to find out what the compiler really did?
Besides, if you did, you should have visited
http://www.mingw.org/bugs.shtml
Not to mention
C++ Syntax (Toggle Plain Text)
$ gcc -W -Wall -ansi -pedantic -O2 foo.c foo.c: In function ‘main’: foo.c:16: warning: ISO C90 does not support the ‘%lf’ printf format foo.c:16: warning: ISO C90 does not support the ‘%lf’ printf format
http://www.mingw.org/mingwfaq.shtml
"MinGW uses the Microsoft runtime libraries, distributed with the Windows operating system"
It does not use the standard GNU LibC implementation, but inherits all the bugs and features of the host libraries.
Maybe by feeding printf() bogus format sequences it's corrupting the stack and the rest of your local variables into the bargain.
Do you still see a problem when you use correct printf format controls?
> Do you have the 3.4.2 version of MinGW? Did you try my code with it? If you did, did you see the weird behaviour I mentioned above?
No, No and No.
Generally speaking, I try and sort out the obvious deficiencies (such as undefined or suspicious behavior) before actually bothering to try and run code myself.
> Adding a '\n' to my printf doesn't make the weird behaviour go away, This advice of
> yours is not only childish but also completely irrelevant to the issue at hand.
Here's chapter and verse from the C89 standard.
•
•
•
•
4.9.2 Streams
Input and output, whether to or from physical devices such as terminals and tape drives, or whether to or from files supported on structured storage devices, are mapped into logical data streams, whose properties are more uniform than their various inputs and outputs. Two forms of mapping are supported, for text streams and for binary streams .99
A text stream is an ordered sequence of characters composed into lines , each line consisting of zero or more characters plus a terminating new-line character. Whether the last line requires a terminating new-line character is implementation-defined. Characters may have to be added, altered, or deleted on input and output to conform to differing conventions for representing text in the host environment. Thus, there need not be a one-to-one correspondence between the characters in a stream and those in the external representation. Data read in from a text stream will necessarily compare equal to the data that were earlier written out to that stream only if: the data consist only of printable characters and the control characters horizontal tab and new-line; no new-line character is immediately preceded by space characters; and the last character is a new-line character. Whether space characters that are written out immediately before a new-line character appear when read in is implementation-defined.
And how would you know whether it was an issue or not, since you have yet to figure out the answer to the question?
•
•
•
•
http://docs.sun.com/source/806-3568/ncg_goldberg.html
http://c-faq.com/fp/fpequal.html
Just because you believe that it "isn't a problem for me" doesn't mean that it isn't a problem. The fact that it works for you sometimes, with some compilers doesn't mean that there isn't a problem.
C++ Syntax (Toggle Plain Text)
double x; for(x = 0; x != 9.9; x += .1) //do something
However the following block from my code is perfectly alright:
C++ Syntax (Toggle Plain Text)
for(i = 0; x0 != x1; ++i) { x0 = x1; x1 = .5 * (x1 + a / x1); //printf("\nIteration %d - converging to %lf - prev value %lf",i,x1,x0); }
•
•
•
•
Statements like this require huge amounts of proof - you don't have that.
Did you disassemble all the generated code to find out what the compiler really did?
As for the format specifier %lf for printf() i don't think it's an issue with MinGW gcc which has implemented a great deal of C99 standard. ABOVE ALL the code works fine when I uncomment the printf() statement not the other way.
•
•
•
•
No, No and No.
Instead of putting up a whole bunch of "this might be the problem"s you could have been more specific. That might have been more useful.
As for printing a final '\n' - that's more of an issue with input streams. Printing a newline to the console is the least of the worries here.
"He who mixes with people and endures the harm they do is better than he who does not mix and endures." (Tirmidhi)
•
•
•
•
Originally Posted by Asif_NSU
LOL, when did statements like "this could very well be a bug with gcc" requires "huge amount of proof".
http://www.catb.org/~esr/faqs/smart-....html#id264997
•
•
•
•
Originally Posted by Asif_NSU
As for the format specifier %lf for printf() i don't think it's an issue with MinGW gcc
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
I never claimed to have found a bug in gcc. I merely suggested that it could be a possibility. If you look at my first post I was here to clarify if it was due to a bug with the gcc or due to something wrong with my code.
So using %lf with printf is undefined behaviour? That is certainly news to me. If that's true there are three possible actions that should be taken:
1. The ones who specified this to be an undefind behaviour in the C standard should be shot dead for creating this confusion in the first place. If %lu is okay why should %lf be not. It sounds so natural.
2. The authors who wrote books on C and said %lf is a valid printf format specifier should be shot dead for misleading/misinforming us.
3. Dave Sinkula, Narue, Ancient Dragon, Rashakifol and everyone else possesing a much better knowledge on C should be shot dead since they did not point this one out to me before;I believe I have used %lf with printf many a times before in this forum.
With all that said my gcc still acts weird even if I use %f instead of %lf with printf (specially when the printf statement was inside a comment after all ). But I guess you can't see it for yourself. So I will take the pain of video recording my desktop activity and posting it here. I am currently posting from elsewhere. I will do so as soon as I get home. I must see it to its end.
•
•
•
•
The general rule of thumb is this: once you do undefined behavior, the rest of the program is undefined.
1. The ones who specified this to be an undefind behaviour in the C standard should be shot dead for creating this confusion in the first place. If %lu is okay why should %lf be not. It sounds so natural.
2. The authors who wrote books on C and said %lf is a valid printf format specifier should be shot dead for misleading/misinforming us.
3. Dave Sinkula, Narue, Ancient Dragon, Rashakifol and everyone else possesing a much better knowledge on C should be shot dead since they did not point this one out to me before;I believe I have used %lf with printf many a times before in this forum.
With all that said my gcc still acts weird even if I use %f instead of %lf with printf (specially when the printf statement was inside a comment after all ). But I guess you can't see it for yourself. So I will take the pain of video recording my desktop activity and posting it here. I am currently posting from elsewhere. I will do so as soon as I get home. I must see it to its end.
"He who mixes with people and endures the harm they do is better than he who does not mix and endures." (Tirmidhi)
![]() |
Similar Threads
- win32 gcc cross compiling for linux target (C)
- Problem with basic templates on GCC (C++)
- from gcc to VC++.Net (C++)
- error when compiling murphy's law with gcc (C)
- installing vmware tools on mandrake 10 (*nix Software)
Other Threads in the C++ Forum
- Previous Thread: finding max value of 10 integers
- Next Thread: New to C++
| Thread Tools | Search this Thread |
api array based beginner bitmap c++ c/c++ calculator char class classes code coding compile compiler console conversion count database delete deploy desktop developer directshow dll download dynamic email encryption error file forms fstream function functions game givemetehcodez google graph gui homeworkhelp homeworkhelper iamthwee ifstream int integer java lib linkedlist linker linux list loop looping loops map math matrix memory multiple news node number output parameter pointer problem program programming project proxy python random read recursion recursive return sorting string strings struct temperature template templates test text text-file tree unix url variable vector video visualstudio win32 windows winsock word wordfrequency wxwidgets






