I'm working with IEEE-754 doubles, and I'd like to verify that the bit patterns match between different platforms. For this reason I would like to see the bit pattern of a double in the Visual Studio C++ Debugger.
I've tried format specifiers, but they don't seem to allow me to format a double as anything which would allow me to see the bit pattern.
One way I finally found was to use Memory View and enter the address of the variable (&x) in the address field. This allows me to set for instance 8-bit integer hex display, which gives me what I need. But is there any other more convenient way of formatting a double this way in the debugger?
To view the exact binary floating-point value you should print the it as hexadecimal with %a/%A or std::hexfloat instead of examining its bit pattern
printf("Hexadecimal: %a %A\n", 1.5, 1.5);
std::out << std::hexfloat << 1.5 << '\n';
However if you really need to view the actual bit pattern then you just need to reinterpret the type of the underlying memory region like auto bits = reinterpret_cast<uint64_t*>(doubleValue). You don't need to open the Memory View to achieve this, a simple cast would work in the Watch window. So to get the bit pattern of double and float use *(__int64*)&doubleValue,x and *(int*)&floatValue,x respectively. Strict aliasing does occur but you don't actually need to care about it in MSVC debugger
Note that __int64 is a built-in type of MSVC so you might want to use long long instead. Typedefs and macros like uint64_t won't work while watching
Alternatively you can access the bytes separately by casting to char* and print as an array with (char*)&doubleValue, 8, (char*)&floatValue, 4 or (char*)&floatingPoint, [sizeof floatingPoint]. This time strict aliasing doesn't occur but the output may be less readable
Related
I'm hoping to improve my debugging workflow by learning how to inspect values faster and with more clarity, but I'm having a big issue.
Visual Studio's C++ debugger makes some assumptions about my memory that aren't always true:
The "Type" of the value may not be how I want to see it's memory printed out
I may want to look at a cstring without 0 terminating the IDE's print out
There might be memory in front of the structure I want to look at
For instance, I might want to look at float value as 0x3f800000 instead of 1.0f, as seeing 0x0000803f instead of 4.60060298822e-41 makes it much easier to see there's an endian encoding issue naturally.
Or when tokenizing, I'll want to look at as many characters as I can scroll through, without NULL ending the print out, and possibly even look in front of this address.
It is possible to use array, 23 to print out 23 characters in array, but this is the only QoL feature I was able to find, and you have to make a bookmark for the variable, so it ends up being very clunky.
Are there any settings or extensions or features I missed, that could improve my ability to see memory in ways Visual Studio might not be able to predict for me?
There are many questions here, sorry if I overlooked some.
For the type, Visual Studio's Watch window can cast. For example, if you have
float f = 1.23;
you can view it as float by just listing its name, or you can cast:
*(int*)&f 0x3f9d70a4 int
For the strings (and looking for memory around your variables) I suggest to use Memory view (Debug -> Windows -> Memory), you get four of those to look at different locations simultaneously. Or at the same location with different formatting. You can put an address of your variable there and some math (- some value). You can view as 1-, 2-, 4- or 8-byte values, Hex or Decimal, ANSI or Unicode, etc. Oh, and yes - you can scroll, pretty far.
For more complex types, you can use natvis
Was trying to port 32bit to 64bit code I was wondering if there are some standard rules when it comes to porting ?
I have my code compiling in a 64bit environment and now I come across some errors like
cast from pointer to integer of different size [-Werror=pointer-to-int-cast] for
x = (int32_t)y;
And to get of this I use x = (size_t)y; I get rid of the error but is this the correct way. Also in various location I have to cast a variable to (unsigned long long). For example
printf("Total Time : %5qu\n",time->compile_time
This gives an error error: format '%qu' expects argument of type 'long long unsigned int', but argument 2 has type (XYZ).
to get this fixed i do something like
printf("Total Time : %5qu\n",(unsigned long long) time->compile_time
Again is this proper ??
I think it's safe to assume that y is a pointer in this case.
Instead of size_t you should use intptr_t or uintptr_t.
See size_t vs. uintptr_t.
As for your second cast it depends what you mean by proper?
The usual advice is to avoid casting. However, like all things in programming there is a reason that they are available. When working on an implementation of malloc on an embedded system I had to cast pointers to uintptr_t in order to be able to do the necessary arithmetic on them. This code was tested on a 64 bit PC but ran on a 32 bit micro controller. The fact that I used two architectures was the best way to ensure it was somewhat portable code.
Casting though makes your code dependent on how the underlying type is defined! Just like you noticed with your x = (int32_t)y this line made your code dependent on the fact that a pointer was 32 bits wide.
The only advice I can give you is to know your types. If you want to cast, it is ok (so long as you can't make your variable of the correct type to begin with) but it may reduce your portability unless you choose the "correct" type to cast to.
The same goes for the printf cast. If I was you, I would read the definition of %5qu thoroughly first (this may help). Then I would attempt to use an appropriately typed variable (or conversely a different format string) and only if that failed would I resort to a cast.
I have never used %qu but I would interpret it as a 64 bit unsigned int so I would try using uint64_t (because long long is not guaranteed to be 64 bits across all platforms). Although by what I read on Wikipedia the q specifier is platform specific to begin with so it might be wise to change it.
Any more than this and the question becomes too broad (it's good that we stuck to specific examples). If you get stuck, come back with individual types that you want to check and ask questions only about them.
Was it Stroustrup that said they call it a 'cast' because it props up something that's broken ? ;-)
x = (int32_t) y;
In this case you are using an exact width type, so it really depends on what x and y are. The error message suggest that y is a pointer. A pointer is not an int32_t, so the real question is why is y being assigned to x ... it may indicate a potential problem. Casting it away may just cover the problem so that it bites you at run-time rather than compile-time. Figure out what the code thinks it's doing and "re-jigger" the types to fit the code. The reason the error goes away when you use a (size_t) cast is that likely the pointer is 64 bits and size_t is 64 bits, but you could consider that a simple form of random casting luck. The same is true when casting to (unsigned long long). Don't assume that an int is 32 or 64 bits and don't using casting as a porting tool ... it will get you in trouble. It's tough to be more specific based on a single line of code. If you want to post a < 25 line function that has issues; more specific advice may be available.
I wrote some parameters (all of type double) to a file for use in performing some complex computations. I write the parameters to the files like so:
refStatsOut << "SomeParam:" << value_of_type_double << endl;
where refStatsOut is an ofstreamparameter. There are four such parameters, each of type double. What I see as written to the file is different from what its actual value is (in terms of loss of precision). As an example, if value_of_type_double had a value -28.07270379934792, then what I see as written in the file is -28.0727.
Also, once these stats have been computed and written I run different programs that use these statistics. The files are read and the values are initially stored as std::strings and then converted to double via atof functions. This results in the values that I have shown above and ruins the computations further down.
My question is this:
1. Is there a way to increase the resolution with which one can write values (of type double and the like) to a file so as to NOT lose any precision?
2. Could this also be a problem of std::string to double conversion with atof? If so, what other function could I use to solve this?
P.S: Please let me know in case some of the details in this question are not clear. I will try to update them and provide more details.
You can use the setprecision function.
ofstream your_file;
you can use your_file.precision(X);
The main difference between precision() and setPrecision() is that precision returns the current precision and setPrecision doesn't. Therefore, you can use precision like this.
streamsize old_precision = your_file.precision(X);
// do what ever you want
//restore precision
your_file.precision(old_precision);
a double is basically a 64-bit integer, if you want a cheap way of writing it out, you can do something like this (note I'm assuming that your compiler uses long for 64-bit ints)
double value = 32985.932235;
long *saveme = (long*)&value;
Just beware of the caveat that the saved value may not remain the same if loaded back on a different architecture.
Is there any compiler that has a directive or a parameter to cast integer calculation to float implicitly. For example:
float f = (1/3)*5;
cout << f;
the "f" is "0", because calculation's constants(1, 3, 10) are integer. I want to convert integer calculation with a compiler directive or parameter. I mean, I won't use explicit casting or ".f" prefix like that:
float f = ((float)1/3)*5;
or
float f = (1.0f/3.0f)*5.0f;
Do you know any c/c++ compiler which has any parameter to do this process without explicit casting or ".f" thing?
Any compiler that did what you want would no longer be a conforming C++ compiler. The semantics of integer division are well specified (at least for positive numbers), and you're proposing to change that.
It would also be dangerous since it would wind up applying to everything, and you might at some point have code that relies on standard integer arithmetic, which would silently be invalid. (After all, if you had tests that would catch that, you presumably would have tests that would catch the undesired integer arithmetic.)
So, the only advice I've got is to write unit tests, have code reviews, and try to avoid magic numbers (instead defining them as const float).
If you don't like either of the two methods you mentioned, you're probably out of luck.
What are you hoping to accomplish with this? Any specialized operator that did "float-division" would have to convert ints to floats at some point after tokenization, which means you're not going to get any performance benefit on the execution.
In C++ it's a bit odd to see a bunch of numeric values sprinkled through the code. Generally it is considered best practice to move any 'magic numbers' like these to their own static const float value, which removes this problem.
No, those two options are the best you have.
I just wonder if there is some convenient way to detect if overflow happens to any variable of any default data type used in a C++ program during runtime? By convenient, I mean no need to write code to follow each variable if it is in the range of its data type every time its value changes. Or if it is impossible to achieve this, how would you do?
For example,
float f1=FLT_MAX+1;
cout << f1 << endl;
doesn't give any error or warning in either compilation with "gcc -W -Wall" or running.
Thanks and regards!
Consider using boosts numeric conversion which gives you negative_overflow and positive_overflow exceptions (examples).
Your example doesn't actually overflow in the default floating-point environment in a IEEE-754 compliant system.
On such a system, where float is 32 bit binary floating point, FLT_MAX is 0x1.fffffep127 in C99 hexadecimal floating point notation. Writing it out as an integer in hex, it looks like this:
0xffffff00000000000000000000000000
Adding one (without rounding, as though the values were arbitrary precision integers), gives:
0xffffff00000000000000000000000001
But in the default floating-point environment on an IEEE-754 compliant system, any value between
0xfffffe80000000000000000000000000
and
0xffffff80000000000000000000000000
(which includes the value you have specified) is rounded to FLT_MAX. No overflow occurs.
Compounding the matter, your expression (FLT_MAX + 1) is likely to be evaluated at compile time, not runtime, since it has no side effects visible to your program.
In situations where I need to detect overflow, I use SafeInt<T>. It's a cross platform solution which throws an exception in overflow situations.
SafeInt<float> f1 = FLT_MAX;
f1 += 1; // throws
It is available on codeplex
http://www.codeplex.com/SafeInt/
Back in the old days when I was developing C++ (199x) we used a tool called Purify. Back then it was a tool that instrumented the object code and logged everything 'bad' during a test run.
I did a quick google and I'm not quite sure if it still exists.
As far as I know nowadays several open source tools exist that do more or less the same.
Checkout electricfence and valgrind.
Clang provides -fsanitize=signed-integer-overflow and -fsanitize=unsigned-integer-overflow.
http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation