Jump to content

Issue with Debug vs. Release Solution configurations in VC++08


Recommended Posts

Hi all,

I am presently creating a program in C++, and part of this program uses the WINAPI QueryPerformanceCounter() function to work out the time taken for certain events.

The issue I am having is when I convert the double that my calculation gives me into a string, using

sprintf(tempbuff, "%.15g", tok->fValue);

When in the 'Debug' solution Config, it works perfectly well, producing numbers like 1.8736523754e+006

However, when in the release solution Config, it will produce something completely wrong:

1873652.3754...

What is causing this? How can I fix the problem? What is the difference between the two configs anyway?

Thankyou in advance.

ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search

Link to comment
Share on other sites

Aren't those numbers the same? One is in scientific notation, the other is not, but appear to me to be the same number.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

i actually just made up those two numbers, they are not actual output.

In any case, that still does not explain the differences caused by Changmg configuration

ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search

Link to comment
Share on other sites

I just ran it again, the correct one outputs something like 2.23..............e+060

the wrong one is like: 22398762363

Entirely different orders of magnitude.

In retrospect...I think they are both wrong, considering in the timeframe its measuring, it should be about 2ms, not 2^60 ms.

if (!QueryPerformanceFrequency((LARGE_INTEGER *)&freq))
        return PARSER_SUCCESS;
    if (!QueryPerformanceCounter((LARGE_INTEGER *)&now))
        return PARSER_SUCCESS;

    result->type = OPT_DOUBLE_TOK;

    result->fValue = (((double)now - (*parameters)[0].fValue) / (double)freq) * 1000.0;
    return PARSER_SUCCESS;
//MOST of tht is from the autoit source. Credit to them.

ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search

Link to comment
Share on other sites

I think it does because a double has finite amount of bits so it needs to be converted to scientific notation. A string can display the entire value as long as it doesn't repeat infinitely. That's my best guess.

Link to comment
Share on other sites

I think it does because a double has finite amount of bits so it needs to be converted to scientific notation. A string can display the entire value as long as it doesn't repeat infinitely. That's my best guess.

How does this account for the differences when compiling in a 'Debug' or 'Release' configuration?

ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search

Link to comment
Share on other sites

How does this account for the differences when compiling in a 'Debug' or 'Release' configuration?

Check if you're not compiling for 32 or 64 bit and the rest of your code adjusts to that according. It's the only thing that changes when you switch debug/release, apart from preprocessors (#ifdef DEBUG in C++ I think).
Link to comment
Share on other sites

You're using C++ so why are you using sprintf()? Use a stream.

I'm guessing you mean using string stream.

does that have much additional overhead over something like sprintf?

ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search

Link to comment
Share on other sites

I'm guessing you mean using string stream.

does that have much additional overhead over something like sprintf?

Yes, creating a string stream object and then using the overloaded operators does create a lot of unnecessary code* if all you need to do is write to a character buffer. Streams are more in the 'spirit' of C++ but the printf variants are still part of the standard CRT library, and do create more compact code. The downside of printf functions is that datatypes aren't able to be checked at compile time. You could also use the _e,_f,_gcvt_s functions..

*edit: by unnecessary code, I mean the resultant code the compiler creates (the stream constructor and allocation of memory, the individual operator calls for each and every type [ "mystream << s << v << endl" = 3 function calls), the reallocation that occurs when the stream buffer is filled [worst-case being for each item inserted in a stream], and the destructor and deallocation of memory when its no longer used..).

Edited by Ascend4nt
Link to comment
Share on other sites

Ascend4nt, I don't really think your post is wise. Experienced C++ programmers can make the choice as to whether or not to use streams but it's incredibly clear we are not dealing with an experienced programmer here. That much is obvious by the complete lack of understanding about what QueryPerformanceCounter() values are. It's also unlikely that the user understands type-safety and just why sprintf() is so dangerous.

Also, why would the compiler generate unnecessary code? It doesn't. It generates necessary code. The code that it generates, however, is often deemed too much for a simple task. There is a pretty clear difference between "lots of code" and "unnecessary code". Type safety and syntactic convenience comes at a price, after all.

All in all not your most impressive post.

Link to comment
Share on other sites

I figured someone would nitpick about the 'unnecessary code' remark in my post, which is why I added the little *footnote. That should have been more than clear enough for anyone reading it to understand that I was responding directly to the overhead question by twitchyliquid. If you want to make this into a debate about 'proper' C++ coding techniques than you're barking up the wrong tree. I don't care about debating abstract ideals. When I program, I liked to get my hands dirty. I learn what is done behind the scenes. And I avoid wasteful techniques whenever possible. For something as simple as converting a float into a string, suggesting the programmer use a stream is overkill. In fact, the best and simplest alternative to that single line in the 1st post is to use _fcvt_s (which I had already offered as an alternative).

All in all not your most impressive post.

How characteristic. Always trying to get digs in whenever possible. Perhaps for once you can leave your ego at the door.

Link to comment
Share on other sites

I figured someone would nitpick about the 'unnecessary code' remark in my post, which is why I added the little *footnote. That should have been more than clear enough for anyone reading it to understand that I was responding directly to the overhead question by twitchyliquid.

You define "unnecessary code" by listing off all code that is necessary. Baffling.

If you want to make this into a debate about 'proper' C++ coding techniques than you're barking up the wrong tree. I don't care about debating abstract ideals.

Clearly you don't care about any ideals because you just told an inexperienced C++ user to use a non-type safe function for something that I believe is no more than a debugging statement.

And I avoid wasteful techniques whenever possible.

This must only be in programming because your post was certainly wasteful. It was bad advice and your meaning was poorly written to the point you knew it was poorly written and chose to try and deflect any notion of that with data that contradicts your own claim. That seems pretty damn wasteful to me.

For something as simple as converting a float into a string, suggesting the programmer use a stream is overkill.

Define overkill. Never mind, don't bother. I don't really care what perverse definition you put to it.

In fact, the best and simplest alternative to that single line in the 1st post is to use _fcvt_s (which I had already offered as an alternative).

I think I liked it better when you weren't suggesting non-standard functions. I don't feel like pointing out why writing portable code is a good thing unless there is a specific demand for platform bound code.

How characteristic. Always trying to get digs in whenever possible. Perhaps for once you can leave your ego at the door.

You gave shit advice and I called you on it. I fail to see how that is "ego". In fact I'm still mystified at this ego people claim I have. I have no ego. I have flashes of arrogance from time to time but no more. I think many of you confuse knowledge and knowledge of self-limits as ego.

Anyway, I decided to take the Harvey Dent approach to your fate on this forum. I flipped a coin. Heads you go away for good, tails you stay another day. Unfortunately the coin landed on tails. Next time I'm not flipping a coin. If you give bad advice to somebody who doesn't know any better I will make you go away. If you try this bullshit analysis crap on me again you will go away. I should remove you now as it's very clear from your parting remark that you did not learn any worthwhile lesson from your previous encounter with me. People who do not learn have no place here.

Plus there's the fact that I just plain don't like you.

Link to comment
Share on other sites

Ascend4nt, I don't really think your post is wise. Experienced C++ programmers can make the choice as to whether or not to use streams but it's incredibly clear we are not dealing with an experienced programmer here. That much is obvious by the complete lack of understanding about what QueryPerformanceCounter() values are. It's also unlikely that the user understands type-safety and just why sprintf() is so dangerous.

Your entirely correct. I am not experienced with C++ (barely been doing it for 6 months). I have no idea what you mean by sprintf() being dangerous (buffer overflows possibly?) and what QueryPerformanceCounter() values actually mean.

ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search

Link to comment
Share on other sites

*If* you are using C, then there is no need to use QueryPerformanceCounter... Especially since your comment shows a parser, which I don't see any reason to need high precision timing. If you want ms precision timing that's simple to use:

clock_t start = clock( );

/* Do stuff */

printf( "%gn", ( clock( ) - start ) / ( ( double )CLOCKS_PER_SEC ) * 1000.0 );
Link to comment
Share on other sites

Mat,

this is an implementation of timerdiff() as a builtin to my interpreter. i must use queryperformancecounter.

ongoing projects:-firestorm: Largescale P2P Social NetworkCompleted Autoit Programs/Scripts: Variable Pickler | Networked Streaming Audio (in pure autoIT) | firenet p2p web messenger | Proxy Checker | Dynamic Execute() Code Generator | P2P UDF | Graph Theory Proof of Concept - Breadth First search

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...