From: Dipanjan D. <its...@gm...> - 2012-08-25 17:38:02
|
Hi, Please consider the snippet below: *#include <stdio.h>* * * *int main()* *{ * * printf("%f\n",1);* * printf("%f\n",(float)1.0);* * printf("%f\n",(int)1.0);* * printf("%f\n",1.0);* * printf("%f\n",1);* *} * The output on MinGW GCC 4.6.2 is: 0.000000 1.000000 1.000000 1.000000 1.000000 Have you noticed the output from line #1 and #5? Code are same, but outputs are different. The same occurs on GCC 4.4 on Ubuntu 10.x also. How can this behavior be explained? -- Thanks & Regards, Dipanjan |
From: JonY <jo...@us...> - 2012-08-25 17:54:54
Attachments:
signature.asc
|
On 8/26/2012 01:37, Dipanjan Das wrote: > Hi, > > Please consider the snippet below: > > *#include <stdio.h>* > * > * > *int main()* > *{ * > * printf("%f\n",1);* > * printf("%f\n",(float)1.0);* > * printf("%f\n",(int)1.0);* > * printf("%f\n",1.0);* > * printf("%f\n",1);* > *} * > > > The output on MinGW GCC 4.6.2 is: > > 0.000000 > 1.000000 > 1.000000 > 1.000000 > 1.000000 > > Have you noticed the output from line #1 and #5? Code are same, but outputs > are different. The same occurs on GCC 4.4 on Ubuntu 10.x also. How can this > behavior be explained? You are writing code with undefined behavior, bad code is bad code, only the 2nd printf is valid. |
From: Dipanjan D. <its...@gm...> - 2012-08-25 18:02:47
|
On 25 August 2012 23:24, JonY <jo...@us...> wrote: > On 8/26/2012 01:37, Dipanjan Das wrote: > > Hi, > > > > Please consider the snippet below: > > > > *#include <stdio.h>* > > * > > * > > *int main()* > > *{ * > > * printf("%f\n",1);* > > * printf("%f\n",(float)1.0);* > > * printf("%f\n",(int)1.0);* > > * printf("%f\n",1.0);* > > * printf("%f\n",1);* > > *} * > > > > > > The output on MinGW GCC 4.6.2 is: > > > > 0.000000 > > 1.000000 > > 1.000000 > > 1.000000 > > 1.000000 > > > > Have you noticed the output from line #1 and #5? Code are same, but > outputs > > are different. The same occurs on GCC 4.4 on Ubuntu 10.x also. How can > this > > behavior be explained? > > > You are writing code with undefined behavior, bad code is bad code, only > the 2nd printf is valid. The points is not of good or bad, but the reason being the code good or bad. I am testing something. Why the first one is invalid? -- Thanks & Regards, Dipanjan |
From: JonY <jo...@us...> - 2012-08-25 18:15:12
Attachments:
signature.asc
|
On 8/26/2012 02:02, Dipanjan Das wrote: > On 25 August 2012 23:24, JonY <jo...@us...> wrote: > >> On 8/26/2012 01:37, Dipanjan Das wrote: >>> Hi, >>> >>> Please consider the snippet below: >>> >>> *#include <stdio.h>* >>> * >>> * >>> *int main()* >>> *{ * >>> * printf("%f\n",1);* >>> * printf("%f\n",(float)1.0);* >>> * printf("%f\n",(int)1.0);* >>> * printf("%f\n",1.0);* >>> * printf("%f\n",1);* >>> *} * >>> >>> >>> The output on MinGW GCC 4.6.2 is: >>> >>> 0.000000 >>> 1.000000 >>> 1.000000 >>> 1.000000 >>> 1.000000 >>> >>> Have you noticed the output from line #1 and #5? Code are same, but >> outputs >>> are different. The same occurs on GCC 4.4 on Ubuntu 10.x also. How can >> this >>> behavior be explained? >> >> > > >> You are writing code with undefined behavior, bad code is bad code, only >> the 2nd printf is valid. > > > The points is not of good or bad, but the reason being the code good or > bad. I am testing something. Why the first one is invalid? Your code is bad because it is undefined behavior, anything can happen, including causing Windows 7 to spontaneously turn into Ubuntu on the next reboot. Printing wrong results is just one of it. %f is for float, not int. Reading the ASM listing will tell you more. See gcc-help for a similar question asked not too long ago. |
From: Dipanjan D. <its...@gm...> - 2012-08-25 18:29:56
|
On 25 August 2012 23:44, JonY <jo...@us...> wrote: > On 8/26/2012 02:02, Dipanjan Das wrote: > > On 25 August 2012 23:24, JonY <jo...@us...> wrote: > > > >> On 8/26/2012 01:37, Dipanjan Das wrote: > >>> Hi, > >>> > >>> Please consider the snippet below: > >>> > >>> *#include <stdio.h>* > >>> * > >>> * > >>> *int main()* > >>> *{ * > >>> * printf("%f\n",1);* > >>> * printf("%f\n",(float)1.0);* > >>> * printf("%f\n",(int)1.0);* > >>> * printf("%f\n",1.0);* > >>> * printf("%f\n",1);* > >>> *} * > >>> > >>> > >>> The output on MinGW GCC 4.6.2 is: > >>> > >>> 0.000000 > >>> 1.000000 > >>> 1.000000 > >>> 1.000000 > >>> 1.000000 > >>> > >>> Have you noticed the output from line #1 and #5? Code are same, but > >> outputs > >>> are different. The same occurs on GCC 4.4 on Ubuntu 10.x also. How can > >> this > >>> behavior be explained? > >> > >> > > > > > >> You are writing code with undefined behavior, bad code is bad code, only > >> the 2nd printf is valid. > > > > > > The points is not of good or bad, but the reason being the code good or > > bad. I am testing something. Why the first one is invalid? > > > Your code is bad because it is undefined behavior, anything can happen, > I am surprised at the point that if the behavior is inconsistent, how can MinGW and GCC procue consistently same o/p on each run? > including causing Windows 7 to spontaneously turn into Ubuntu on the > next reboot. Printing wrong results is just one of it. > Can it happen the other way round, i.e. turning Ubuntu to Win 7? > %f is for float, not int. Reading the ASM listing will tell you more. > > See gcc-help for a similar question asked not too long ago. > > If you have the link, please share. -- Thanks & Regards, Dipanjan |
From: Jan R. <tr...@mx...> - 2012-08-26 12:14:00
|
>>>>> *int main()* >>>>> *{ * >>>>> * printf("%f\n",1);* >>>>> * printf("%f\n",(float)1.0);* >>>>> * printf("%f\n",(int)1.0);* >>>>> * printf("%f\n",1.0);* >>>>> * printf("%f\n",1);* >>>>> *} * >>>>> >>>>> The output on MinGW GCC 4.6.2 is: >>>>> >>>>> 0.000000 >>>>> 1.000000 >>>>> 1.000000 >>>>> 1.000000 >>>>> 1.000000 >>>>> >>>>> Have you noticed the output from line #1 and #5? Code are same, but >>>>> outputs >>>>> are different. The same occurs on GCC 4.4 on Ubuntu 10.x also. How can >>>>> this >>>>> behavior be explained? >>>> >>>> You are writing code with undefined behavior, bad code is bad code, >>>> only >>>> the 2nd printf is valid. >>> >>> The points is not of good or bad, but the reason being the code good or >>> bad. I am testing something. Why the first one is invalid? >> >> Your code is bad because it is undefined behavior, anything can happen, > > I am surprised at the point that if the behavior is inconsistent, how can > MinGW and GCC procue consistently same o/p on each run? > Your lines 1 and 3 print different result because, for ellipsis call, floats (converted to doubles) are passed on x87 pseudo-stack, not on *the* stack. That is true for GCC/MinGW. So on line 1, you pushed the value onto the stack, but printf reads from x87 stack, where there is nothing (default-initialized to zeros). On your line 3, you repeat the situation, but you get 1.0 because that value was placed on top of the x87 stack by line 2. But don't rely on it being this way. Everything written above still applies. GCC will happily throw this kind of code away when optimizing any slightly more complicated block of code. --- Jan Ringoš, http://tringi.mx-3.cz software architect, programmer |
From: Dipanjan D. <its...@gm...> - 2012-08-26 13:10:29
|
On 26 August 2012 17:42, Jan Ringoš <tr...@mx...> wrote: > >>>>> *int main()* > >>>>> *{ * > >>>>> * printf("%f\n",1);* > >>>>> * printf("%f\n",(float)1.0);* > >>>>> * printf("%f\n",(int)1.0);* > >>>>> * printf("%f\n",1.0);* > >>>>> * printf("%f\n",1);* > >>>>> *} * > >>>>> > >>>>> The output on MinGW GCC 4.6.2 is: > >>>>> > >>>>> 0.000000 > >>>>> 1.000000 > >>>>> 1.000000 > >>>>> 1.000000 > >>>>> 1.000000 > >>>>> > >>>>> Have you noticed the output from line #1 and #5? Code are same, but > >>>>> outputs > >>>>> are different. The same occurs on GCC 4.4 on Ubuntu 10.x also. How > can > >>>>> this > >>>>> behavior be explained? > >>>> > >>>> You are writing code with undefined behavior, bad code is bad code, > >>>> only > >>>> the 2nd printf is valid. > >>> > >>> The points is not of good or bad, but the reason being the code good or > >>> bad. I am testing something. Why the first one is invalid? > >> > >> Your code is bad because it is undefined behavior, anything can happen, > > > > I am surprised at the point that if the behavior is inconsistent, how can > > MinGW and GCC procue consistently same o/p on each run? > > > > > Your lines 1 and 3 print different result because, for ellipsis call, > floats > (converted to doubles) are passed on x87 pseudo-stack, not on *the* stack. > That is true for GCC/MinGW. So on line 1, you pushed the value onto the > stack, but printf reads from x87 stack, where there is nothing > (default-initialized to zeros). On your line 3, you repeat the situation, > but you get 1.0 because that value was placed on top of the x87 stack by > line 2. > > But don't rely on it being this way. Everything written above still > applies. > GCC will happily throw this kind of code away when optimizing any slightly > more complicated block of code. > > Hello Jan, Here are few points which I don't understand: 1. The term pseudo-stack is new to me. I am going to study how it works. In the mean time, can you please give me an one-liner regarding what it is. 2. When statement #2 pushes the value onto x87 stack, doesn't it pop it off from it simultaneously while printing? Why a "stale" value is still available for statement #3? 3. Consider the snippet below: #include <stdio.h> int main() { printf("6. %f\n",(float)9/5); printf("7. %f\n",1); } The output it produces is: 6. 1.800000 7. 1.799999 While there is nothing wrong with #6, I surprise why the representation gets a little bit imprecise while it comes to #7. Following your logic, #6 pushes 1.8 as a 64bit double value onto x87 pseudo-stack. Statement #7, instead of pushing an integer 1 onto it, reads back from the x87 stack again. But, how many bits does it read out? The same 64 bits, isn't it? Then why does the value differ second time? ******************************************************************************************************************************************************************* NOTE: Many are concerned that this is bad coding practice. Be assured that such codes are not going to get executed in any production/real-time environments. Above are initially inspired by an exam question and further carried out out of my own curiosity. ******************************************************************************************************************************************************************* -- Thanks & Regards, Dipanjan |
From: Jan R. <tr...@mx...> - 2012-08-26 19:39:37
|
> Hello Jan, > Here are few points which I don't understand: > The term pseudo-stack is new to me. I am going to study how it works. In > the mean time, can you please give me an one-liner regarding what it is. It is not really a term. Pseudo just means that something pretends to be something else but not really. In this case, it is just 8 registers that are usually accessed through several x87 instructions that emulate push and pop operations and rotate the contents around these registers. There is a good summary on wikipedia. > When statement #2 pushes the value onto x87 stack, doesn't it pop it off > from it simultaneously while printing? Why a "stale" value is still > available for statement #3? As it is not actually a stack, there is no SP to go wild, it does not need to be correctly cleared. Printf just reads the top. > Consider the snippet below: > [...] > While there is nothing wrong with #6, I surprise why the representation > gets a little bit imprecise while it comes to #7. Following your logic, #6 > pushes 1.8 as a 64bit double value onto x87 pseudo-stack. Statement #7, > instead of pushing an integer 1 onto it, reads back from the x87 stack > again. But, how many bits does it read out? The same 64 bits, isn't it? > Then why does the value differ second time? The value might differ due to many different reasons, but I would be really speculating here. To be sure, you would need to relate documentation for x87 precission settings to GCC libC implementation of printing doubles. > NOTE: Many are concerned that this is bad coding practice. Be assured that > such codes are not going to get executed in any production/real-time > environments. Above are initially inspired by an exam question and further > carried out out of my own curiosity. I understand. I love investigating such low-level behavior and improving my knowledge of "my" platform, but I would be very careful before relying on it in production C++ code. --- Jan Ringoš, http://tringi.mx-3.cz software architect, programmer |
From: Keith M. <kei...@us...> - 2012-08-25 18:14:31
|
On 25/08/12 18:54, JonY wrote: > On 8/26/2012 01:37, Dipanjan Das wrote: >> Please consider the snippet below: >> >> *#include <stdio.h>* >> * >> * >> *int main()* >> *{ * >> * printf("%f\n",1);* >> * printf("%f\n",(float)1.0);* >> * printf("%f\n",(int)1.0);* >> * printf("%f\n",1.0);* >> * printf("%f\n",1);* >> *} * >> >> ... snip ... >> > > You are writing code with undefined behavior, bad code is bad code, only > the 2nd printf is valid. Actually, both the 2nd and the 4th are valid; both pass an argument which is promoted to type "double", (a 64-bit entity). The remaining three pass an argument of type "int", which is only 32 bits, but the "%f" format specifier expects, and consumes 64 bits regardless. When you pass only 32 bits, the other 32 required could represent anything at all -- hence behaviour is undefined. JonY is right; your code is wrong, and you can have no expectation of consistent results. -- Regards, Keith. |
From: Dipanjan D. <its...@gm...> - 2012-08-25 18:21:56
|
On 25 August 2012 23:44, Keith Marshall <kei...@us... > wrote: > On 25/08/12 18:54, JonY wrote: > > On 8/26/2012 01:37, Dipanjan Das wrote: > >> Please consider the snippet below: > >> > >> *#include <stdio.h>* > >> * > >> * > >> *int main()* > >> *{ * > >> * printf("%f\n",1);* > >> * printf("%f\n",(float)1.0);* > >> * printf("%f\n",(int)1.0);* > >> * printf("%f\n",1.0);* > >> * printf("%f\n",1);* > >> *} * > >> > >> ... snip ... > >> > > > > You are writing code with undefined behavior, bad code is bad code, only > > the 2nd printf is valid. > > > Actually, both the 2nd and the 4th are valid; both pass an argument > which is promoted to type "double", (a 64-bit entity). The remaining > three pass an argument of type "int", which is only 32 bits, but the > "%f" format specifier expects, and consumes 64 bits regardless. When > you pass only 32 bits, the other 32 required could represent anything at > all -- hence behaviour is undefined. JonY is right; your code is wrong, > and you can have no expectation of consistent results. > > But, on Turbo C compiler, the first line produces "Floating point format not linked" error. I have not found the reason of this behavior though I have come across it many a times. -- Thanks & Regards, Dipanjan |
From: Earnie B. <ea...@us...> - 2012-08-26 01:39:15
|
On Sat, Aug 25, 2012 at 2:21 PM, Dipanjan Das wrote: > > But, on Turbo C compiler, the first line produces "Floating point format not > linked" error. I have not found the reason of this behavior though I have > come across it many a times. > Undefined behavior means that the compiler is left to decide how to deal with the bad code. Try using the following options when compiling your code: -Wall -Werror -pedantic. These three will force an error when you do not follow a standard. -- Earnie -- https://sites.google.com/site/earnieboyd |
From: JonY <jo...@us...> - 2012-08-26 00:57:37
Attachments:
signature.asc
|
On 8/26/2012 02:21, Dipanjan Das wrote: > On 25 August 2012 23:44, Keith Marshall <kei...@us... >> wrote: > >> On 25/08/12 18:54, JonY wrote: >>> On 8/26/2012 01:37, Dipanjan Das wrote: >>>> Please consider the snippet below: >>>> >>>> *#include <stdio.h>* >>>> * >>>> * >>>> *int main()* >>>> *{ * >>>> * printf("%f\n",1);* >>>> * printf("%f\n",(float)1.0);* >>>> * printf("%f\n",(int)1.0);* >>>> * printf("%f\n",1.0);* >>>> * printf("%f\n",1);* >>>> *} * >>>> >>>> ... snip ... >>>> >>> >>> You are writing code with undefined behavior, bad code is bad code, only >>> the 2nd printf is valid. >> >> > > >> Actually, both the 2nd and the 4th are valid; both pass an argument >> which is promoted to type "double", (a 64-bit entity). The remaining >> three pass an argument of type "int", which is only 32 bits, but the >> "%f" format specifier expects, and consumes 64 bits regardless. When >> you pass only 32 bits, the other 32 required could represent anything at >> all -- hence behaviour is undefined. JonY is right; your code is wrong, >> and you can have no expectation of consistent results. >> >> > But, on Turbo C compiler, the first line produces "Floating point format > not linked" error. I have not found the reason of this behavior though I > have come across it many a times. > It is part of the reason why your code is undefined, it does not conform to C standards. Some compilers may warn, others not, effects are entirely up to the compiler, OS and hardware combination. |
From: JonY <jo...@us...> - 2012-08-26 01:02:25
Attachments:
signature.asc
|
On 8/26/2012 02:29, Dipanjan Das wrote: > On 25 August 2012 23:44, JonY <jo...@us...> wrote: > >> On 8/26/2012 02:02, Dipanjan Das wrote: >>> On 25 August 2012 23:24, JonY <jo...@us...> wrote: >>> >>>> On 8/26/2012 01:37, Dipanjan Das wrote: >>>>> Hi, >>>>> >>>>> Please consider the snippet below: >>>>> >>>>> *#include <stdio.h>* >>>>> * >>>>> * >>>>> *int main()* >>>>> *{ * >>>>> * printf("%f\n",1);* >>>>> * printf("%f\n",(float)1.0);* >>>>> * printf("%f\n",(int)1.0);* >>>>> * printf("%f\n",1.0);* >>>>> * printf("%f\n",1);* >>>>> *} * >>>>> >>>>> >>>>> The output on MinGW GCC 4.6.2 is: >>>>> >>>>> 0.000000 >>>>> 1.000000 >>>>> 1.000000 >>>>> 1.000000 >>>>> 1.000000 >>>>> >>>>> Have you noticed the output from line #1 and #5? Code are same, but >>>> outputs >>>>> are different. The same occurs on GCC 4.4 on Ubuntu 10.x also. How can >>>> this >>>>> behavior be explained? >>>> >>>> >>> >>> >>>> You are writing code with undefined behavior, bad code is bad code, only >>>> the 2nd printf is valid. >>> >>> >>> The points is not of good or bad, but the reason being the code good or >>> bad. I am testing something. Why the first one is invalid? >> >> > > >> Your code is bad because it is undefined behavior, anything can happen, >> > > I am surprised at the point that if the behavior is inconsistent, how can > MinGW and GCC procue consistently same o/p on each run? > > It can't, because your code is not correct at all, as highlighted, does not conform to C. It is up to the various combinations of hardware and software to produce random results. Basically, a classic PEBKAC issue, if you don't mind the term. > >> including causing Windows 7 to spontaneously turn into Ubuntu on the >> next reboot. Printing wrong results is just one of it. >> > > Can it happen the other way round, i.e. turning Ubuntu to Win 7? > > Sure, it might even produce a product key for free in the process. > >> %f is for float, not int. Reading the ASM listing will tell you more. >> >> See gcc-help for a similar question asked not too long ago. >> >> > If you have the link, please share. http://comments.gmane.org/gmane.comp.gcc.help/42393 |
From: Dipanjan D. <its...@gm...> - 2012-08-26 02:42:22
|
On 26 August 2012 06:32, JonY <jo...@us...> wrote: > On 8/26/2012 02:29, Dipanjan Das wrote: > > On 25 August 2012 23:44, JonY <jo...@us...> wrote: > > > >> On 8/26/2012 02:02, Dipanjan Das wrote: > >>> On 25 August 2012 23:24, JonY <jo...@us...> wrote: > >>> > >>>> On 8/26/2012 01:37, Dipanjan Das wrote: > >>>>> Hi, > >>>>> > >>>>> Please consider the snippet below: > >>>>> > >>>>> *#include <stdio.h>* > >>>>> * > >>>>> * > >>>>> *int main()* > >>>>> *{ * > >>>>> * printf("%f\n",1);* > >>>>> * printf("%f\n",(float)1.0);* > >>>>> * printf("%f\n",(int)1.0);* > >>>>> * printf("%f\n",1.0);* > >>>>> * printf("%f\n",1);* > >>>>> *} * > >>>>> > >>>>> > >>>>> The output on MinGW GCC 4.6.2 is: > >>>>> > >>>>> 0.000000 > >>>>> 1.000000 > >>>>> 1.000000 > >>>>> 1.000000 > >>>>> 1.000000 > >>>>> > >>>>> Have you noticed the output from line #1 and #5? Code are same, but > >>>> outputs > >>>>> are different. The same occurs on GCC 4.4 on Ubuntu 10.x also. How > can > >>>> this > >>>>> behavior be explained? > >>>> > >>>> > >>> > >>> > >>>> You are writing code with undefined behavior, bad code is bad code, > only > >>>> the 2nd printf is valid. > >>> > >>> > >>> The points is not of good or bad, but the reason being the code good or > >>> bad. I am testing something. Why the first one is invalid? > >> > >> > > > > > >> Your code is bad because it is undefined behavior, anything can happen, > >> > > > > I am surprised at the point that if the behavior is inconsistent, how can > > MinGW and GCC procue consistently same o/p on each run? > > > > > > It can't, because your code is not correct at all, as highlighted, does > not conform to C. It is up to the various combinations of hardware and > software to produce random results. > > > Basically, a classic PEBKAC issue, if you don't mind the term. > Nah! I didn't mind at all as let me tell you, this snippet was not written by me at all but some "wanna-b-C-expert "type paper setter of some prestigious examination held across the country. > > > > >> including causing Windows 7 to spontaneously turn into Ubuntu on the > >> next reboot. Printing wrong results is just one of it. > >> > > > > Can it happen the other way round, i.e. turning Ubuntu to Win 7? > > > > > > > Sure, it might even produce a product key for free in the process. > Let us not publish these few lines in public domain them...husssshhhhhh...keep it secret. > > > > >> %f is for float, not int. Reading the ASM listing will tell you more. > >> > >> See gcc-help for a similar question asked not too long ago. > >> > >> > > If you have the link, please share. > > http://comments.gmane.org/gmane.comp.gcc.help/42393 > > Hmm...thanks > > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > MinGW-users mailing list > Min...@li... > > This list observes the Etiquette found at > http://www.mingw.org/Mailing_Lists. > We ask that you be polite and do the same. Disregard for the list > etiquette may cause your account to be moderated. > > _______________________________________________ > You may change your MinGW Account Options or unsubscribe at: > https://lists.sourceforge.net/lists/listinfo/mingw-users > Also: mailto:min...@li...?subject=unsubscribe > -- Thanks & Regards, Dipanjan |
From: Dipanjan D. <its...@gm...> - 2012-08-26 02:49:09
|
On 26 August 2012 06:27, JonY <jo...@us...> wrote: > On 8/26/2012 02:21, Dipanjan Das wrote: > > On 25 August 2012 23:44, Keith Marshall < > kei...@us... > >> wrote: > > > >> On 25/08/12 18:54, JonY wrote: > >>> On 8/26/2012 01:37, Dipanjan Das wrote: > >>>> Please consider the snippet below: > >>>> > >>>> *#include <stdio.h>* > >>>> * > >>>> * > >>>> *int main()* > >>>> *{ * > >>>> * printf("%f\n",1);* > >>>> * printf("%f\n",(float)1.0);* > >>>> * printf("%f\n",(int)1.0);* > >>>> * printf("%f\n",1.0);* > >>>> * printf("%f\n",1);* > >>>> *} * > >>>> > >>>> ... snip ... > >>>> > >>> > >>> You are writing code with undefined behavior, bad code is bad code, > only > >>> the 2nd printf is valid. > >> > >> > > > > > >> Actually, both the 2nd and the 4th are valid; both pass an argument > >> which is promoted to type "double", (a 64-bit entity). The remaining > >> three pass an argument of type "int", which is only 32 bits, but the > >> "%f" format specifier expects, and consumes 64 bits regardless. When > >> you pass only 32 bits, the other 32 required could represent anything at > >> all -- hence behaviour is undefined. JonY is right; your code is wrong, > >> and you can have no expectation of consistent results. > >> > >> > > But, on Turbo C compiler, the first line produces "Floating point format > > not linked" error. I have not found the reason of this behavior though I > > have come across it many a times. > > > > > It is part of the reason why your code is undefined, it does not conform > to C standards. > > Some compilers may warn, others not, effects are entirely up to the > compiler, OS and hardware combination. > > Does any such "Floating point format not linked error" exist in MinGW gcc? If so, then what does it actually mean? I have searched for this message many times earlier, but every webpage and every discussion I found, people interpret it in their own way which never satisfied me. -- Thanks & Regards, Dipanjan |
From: Greg C. <gch...@sb...> - 2012-08-26 09:54:06
|
On 2012-08-26 02:49Z, Dipanjan Das wrote: [...] >> On 8/26/2012 02:21, Dipanjan Das wrote: >> > But, on Turbo C compiler, the first line produces "Floating point format >> > not linked" error. I have not found the reason of this behavior though I >> > have come across it many a times. [...] > Does any such "Floating point format not linked error" exist in MinGW gcc? > If so, then what does it actually mean? I have searched for this message > many times earlier, but every webpage and every discussion I found, people > interpret it in their own way which never satisfied me. Here is the complete, authoritative answer from the original vendor: http://web.archive.org/web/19970614025333/http://www.borland.com/devsupport/borlandcpp/ti/TI645.html The library code that formats floating-point numbers consumed something on the order of a kilobyte. This ancient compiler didn't include that code by default; in those days, a kilobyte was important. Dennis Ritchie's original C compiler for the PDP-11 also had this optimization. The page above tells you how to work around it. |
From: Dipanjan D. <its...@gm...> - 2012-08-26 11:55:07
|
On 26 August 2012 15:23, Greg Chicares <gch...@sb...> wrote: > On 2012-08-26 02:49Z, Dipanjan Das wrote: > [...] > >> On 8/26/2012 02:21, Dipanjan Das wrote: > >> > But, on Turbo C compiler, the first line produces "Floating point > format > >> > not linked" error. I have not found the reason of this behavior > though I > >> > have come across it many a times. > [...] > > Does any such "Floating point format not linked error" exist in MinGW > gcc? > > If so, then what does it actually mean? I have searched for this message > > many times earlier, but every webpage and every discussion I found, > people > > interpret it in their own way which never satisfied me. > > > Here is the complete, authoritative answer from the original vendor: > > > http://web.archive.org/web/19970614025333/http://www.borland.com/devsupport/borlandcpp/ti/TI645.html > > The library code that formats floating-point numbers consumed something > on the order of a kilobyte. This ancient compiler didn't include that code > by default; in those days, a kilobyte was important. Dennis Ritchie's > original C compiler for the PDP-11 also had this optimization. The page > above tells you how to work around it. > > Thank you a lot. I have searched for several times but ended up reading plethora of pages colored with people's imagination rather than the true answer from "horse's mouth". Thanks again. -- Thanks & Regards, Dipanjan |
From: K. F. <kfr...@gm...> - 2012-08-26 15:49:55
|
Hello Dipanjan! I don't know the answer to your specific question, but I offer a couple of comments, and some perspective, below. On Sun, Aug 26, 2012 at 9:10 AM, Dipanjan Das <its...@gm...> wrote: > > On 26 August 2012 17:42, Jan Ringoš <tr...@mx...> wrote: >> ... >> >>>>> ... >> >>>>> * printf("%f\n",1);* >> >>>>> ... >> >>>>> Have you noticed the output from line #1 and #5? Code are same, but >> >>>>> outputs >> >>>>> How >> >>>>> can >> >>>>> this >> >>>>> behavior be explained? >> >>>> >> >>>> You are writing code with undefined behavior, bad code is bad code, >> >>>> ... "Undefined behavior" is the short answer to your questions. A legal, compliant C compiler is allowed to do whatever it wants (that's what "undefined" means) when confronted with your code. A compiler might try to help you by detecting the possibility that you made an error and issuing a warning, but it doesn't have to. (As an aside, in general the compiler can't detect this kind of error. That is most likely why the standard leaves it as undefined behavior. Two things about your line of code, printf("%f\n",1);: First, printf is a function call so in a straightforward compiler implementation, when the compiler compiles that line of code, it doesn't know what the function printf is going to do with its first argument, "%f\n", so it can't detect the error. Of course, because printf is a standard function, a more sophisticated compiler might, indeed, know what printf does, but that would impose more work on the compiler writers, something the standard elects not to do. Second, and more importantly, the first argument of printf can be the result of a computation. In such a case the compiler simply cannot know at compile time what the value of that argument might be at run time, so it can't detect the error in the general case. Of course, when the first argument of printf is a string literal, a smart compiler is able to detect the error, but the standard does not require it,) >> >> ... >> >> Your code is bad because it is undefined behavior, anything can happen, >> > >> > I am surprised at the point that if the behavior is inconsistent, how >> > can >> > MinGW and GCC procue consistently same o/p on each run? Undefined behavior -- you shouldn't be surprised. > ... >> Your lines 1 and 3 print different result because, for ellipsis call, >> floats >> (converted to doubles) are passed on x87 pseudo-stack, not on *the* stack. >> That is true for GCC/MinGW. So on line 1, you pushed the value onto the >> stack, but printf reads from x87 stack, where there is nothing >> (default-initialized to zeros). On your line 3, you repeat the situation, >> but you get 1.0 because that value was placed on top of the x87 stack by >> line 2. >> >> But don't rely on it being this way. Yup. Can't rely on undefined behavior being this way. >> ... > > Hello Jan, > > Here are few points which I don't understand: > > The term pseudo-stack is new to me. I am going to study how it works. In the > mean time, can you please give me an one-liner regarding what it is. I don't know what the pseudo-stack is either. I also don't really care. While I suppose that the question is technically on topic on a mingw list ("Does mingw use a pseudo-stack, and, if so, what is it?"), my guess is that this might not be the best list for such a discussion. (Maybe a gcc list, or a list for compiler design.) Most participants on this list will tell you that undefined behavior may or may not cause a pseudo-stack that may or may not exist to produce a result that may or may not be the result expected by you. > When statement #2 pushes the value onto x87 stack, doesn't it pop it off > from it simultaneously while printing? Why a "stale" value is still > available for statement #3? > Consider the snippet below: > > #include <stdio.h> > > int main() > { > printf("6. %f\n",(float)9/5); > printf("7. %f\n",1); > } > > The output it produces is: > > 6. 1.800000 > 7. 1.799999 > > While there is nothing wrong with #6, I surprise why the representation gets > a little bit imprecise while it comes to #7. Following your logic, #6 pushes > 1.8 as a 64bit double value onto x87 pseudo-stack. Statement #7, instead of > pushing an integer 1 onto it, reads back from the x87 stack again. But, how > many bits does it read out? The same 64 bits, isn't it? Then why does the > value differ second time? > ... Well, again the short answer is "undefined behavior." But the details of how gcc / mingw happens to implement this particular bit of undefined behavior is a legitimate and potentially interesting question (but maybe better addressed to a gcc of compiler list), but one to which I do not know the answer. If I wanted to find out the answer, I would look at the assembly language produced by the compiler ("gcc -S"), and all would be revealed. > > Thanks & Regards, > > Dipanjan Happy (Assembler) Hacking! K. Frank |
From: Dipanjan D. <its...@gm...> - 2012-08-26 16:15:26
|
On 26 August 2012 21:19, K. Frank <kfr...@gm...> wrote: > Hello Dipanjan! > > I don't know the answer to your specific question, but I offer a couple of > comments, and some perspective, below. > > On Sun, Aug 26, 2012 at 9:10 AM, Dipanjan Das > <its...@gm...> wrote: > > > > On 26 August 2012 17:42, Jan Ringoš <tr...@mx...> wrote: > >> ... > >> >>>>> ... > >> >>>>> * printf("%f\n",1);* > >> >>>>> ... > >> >>>>> Have you noticed the output from line #1 and #5? Code are same, > but > >> >>>>> outputs > >> >>>>> How > >> >>>>> can > >> >>>>> this > >> >>>>> behavior be explained? > >> >>>> > >> >>>> You are writing code with undefined behavior, bad code is bad code, > >> >>>> ... > > "Undefined behavior" is the short answer to your questions. A legal, > compliant > C compiler is allowed to do whatever it wants (that's what "undefined" > means) > when confronted with your code. A compiler might try to help you by > detecting > the possibility that you made an error and issuing a warning, but it > doesn't > have to. > > (As an aside, in general the compiler can't detect this kind of error. > That is > most likely why the standard leaves it as undefined behavior. Two things > about your line of code, printf("%f\n",1);: First, printf is a function > call so > in a straightforward compiler implementation, when the compiler compiles > that line of code, it doesn't know what the function printf is going to do > with > its first argument, "%f\n", so it can't detect the error. Of course, > because > printf is a standard function, a more sophisticated compiler might, indeed, > know what printf does, but that would impose more work on the compiler > writers, something the standard elects not to do. Second, and more > importantly, the first argument of printf can be the result of a > computation. > In such a case the compiler simply cannot know at compile time what the > value of that argument might be at run time, so it can't detect the error > in > the general case. Of course, when the first argument of printf is a string > literal, a smart compiler is able to detect the error, but the standard > does > not require it,) > > >> >> ... > >> >> Your code is bad because it is undefined behavior, anything can > happen, > >> > > >> > I am surprised at the point that if the behavior is inconsistent, how > >> > can > >> > MinGW and GCC procue consistently same o/p on each run? > > Undefined behavior -- you shouldn't be surprised. > > > ... > >> Your lines 1 and 3 print different result because, for ellipsis call, > >> floats > >> (converted to doubles) are passed on x87 pseudo-stack, not on *the* > stack. > >> That is true for GCC/MinGW. So on line 1, you pushed the value onto the > >> stack, but printf reads from x87 stack, where there is nothing > >> (default-initialized to zeros). On your line 3, you repeat the > situation, > >> but you get 1.0 because that value was placed on top of the x87 stack by > >> line 2. > >> > >> But don't rely on it being this way. > > Yup. Can't rely on undefined behavior being this way. > > >> ... > > > > Hello Jan, > > > > Here are few points which I don't understand: > > > > The term pseudo-stack is new to me. I am going to study how it works. In > the > > mean time, can you please give me an one-liner regarding what it is. > > I don't know what the pseudo-stack is either. I also don't really care. > While I suppose that the question is technically on topic on a mingw > list ("Does mingw use a pseudo-stack, and, if so, what is it?"), my > guess is that this might not be the best list for such a discussion. > (Maybe a gcc list, or a list for compiler design.) Most participants on > this list will tell you that undefined behavior may or may not cause a > pseudo-stack that may or may not exist to produce a result that may > or may not be the result expected by you. > > > When statement #2 pushes the value onto x87 stack, doesn't it pop it off > > from it simultaneously while printing? Why a "stale" value is still > > available for statement #3? > > Consider the snippet below: > > > > #include <stdio.h> > > > > int main() > > { > > printf("6. %f\n",(float)9/5); > > printf("7. %f\n",1); > > } > > > > The output it produces is: > > > > 6. 1.800000 > > 7. 1.799999 > > > > While there is nothing wrong with #6, I surprise why the representation > gets > > a little bit imprecise while it comes to #7. Following your logic, #6 > pushes > > 1.8 as a 64bit double value onto x87 pseudo-stack. Statement #7, instead > of > > pushing an integer 1 onto it, reads back from the x87 stack again. But, > how > > many bits does it read out? The same 64 bits, isn't it? Then why does the > > value differ second time? > > ... > > > Well, again the short answer is "undefined behavior." But the details of > how > gcc / mingw happens to implement this particular bit of undefined behavior > is > a legitimate and potentially interesting question (but maybe better > addressed > to a gcc of compiler list), but one to which I do not know the answer. > > If I wanted to find out the answer, I would look at the assembly language > produced by the compiler ("gcc -S"), and all would be revealed. > > Here is what gcc -S produces. I am not familiar with few of the used opcodes. Hope it rings a bell to someone else. .file "demo2.c" .section .rodata .LC0: .string "6. %f\n" .LC2: .string "7. %f\n" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp movl $.LC0, %eax fldl .LC1 fstpl 4(%esp) movl %eax, (%esp) call printf movl $.LC2, %eax movl $1, 4(%esp) movl %eax, (%esp) call printf leave ret .size main, .-main .section .rodata .align 8 .LC1: .long -1073741824 .long 1073532108 .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" .section .note.GNU-stack,"",@progbits > > > > Thanks & Regards, > > > > Dipanjan > > Happy (Assembler) Hacking! > > > K. Frank > > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > MinGW-users mailing list > Min...@li... > > This list observes the Etiquette found at > http://www.mingw.org/Mailing_Lists. > We ask that you be polite and do the same. Disregard for the list > etiquette may cause your account to be moderated. > > _______________________________________________ > You may change your MinGW Account Options or unsubscribe at: > https://lists.sourceforge.net/lists/listinfo/mingw-users > Also: mailto:min...@li...?subject=unsubscribe -- Thanks & Regards, Dipanjan |