VC++ compiler and type conversion? - c++

When I moved a program from a Mac to this Windows PC, the VC++ 2008 compiler is giving me errors for passing unsigned ints to the cmath pow() function. As I understand, this function is not overloaded to accept anything but floating-point numbers.
Is there some compiler flag/setting that will ignore these errors? Also does anyone know how to find the documentation on the VC++ compiler?
Edit
This isn't a warning, it's an error. However, for me it's not an issue since my program is only dealing with numbers that come out as integers, so I don't care that they aren't floats. If it was just warnings I would move on with my life, but it's not letting me compile. Can I suppress errors somehow? Like I said, the errors aren't coming up on my Mac and the program is fine.

Regarding other answers here, it is not a good idea to tell the question author to turn off this warning. His code is broken - he's passing an unsigned int instead of a float. You should be telling him to fix his code!
This isn't a warning, it's an error. However, for me it's not an issue since my
program is only dealing with numbers that come out as integers, so I don't care that
they aren't floats. If it was just warnings I would move on with my life, but it's not
letting me compile. Can I suppress errors somehow? Like I said, the errors aren't
coming up on my Mac and the program is fine.
Integers and floats use different representations internally. If you have the same number in an int and a float, the bit pattern inside the storage for them is completely different. You cannot under any circumstances whatsoever expect your code to work if you are passing an integer when you should be passing a float.
Furthermore, I assert your Mac code either is silently using an overloaded version of that function (e.g. you are on that platform compiling with C++) or you believe it works when in fact it is working by chance or is not actually working.
Addendum
No compilers ever written has the ability to turn off errors.
A warning means the compiler thinks you're making a mistake.
An error means the compiler doesn't know what to do.

There are a couple of options:
In C, the solution is simply to cast the ints to doubles:
pow((double)i, (double)j)
In C++, you can do the same, although you should use a C++-style cast:
pow(static_cast<double>(i), static_cast<double>(j))
But a better idea is to use the overload C++ provides:
std::pow(static_cast<double>(i), j);
The base still has to be a floating-point value, but the exponent can be an int at least
The std:: prefix probably isn't necessary (most compilers make the function available in the global namespace as well).
Of course, to access the C++ versions of the function, you have to include the C++ version of the header.
So instead of #include <math.h> you need to #include <cmath>
C++ provides C++ versions of every C header, using this naming convention. If the C header is called foo.h, the C++ version will be cfoo. When you're writing in C++, you should always prefer these versions.

I don't know of a flag, but getting rid of the warnings was easy enough for me. Just double click on each of the warnings in the "Task List" and add the appropriate casting, whether you prefer
(double) my_variable
or
static_cast<double>(my_variable)
I'm guessing if you're getting the ambiguous warning, there are multiple pow functions defined somewhere. It's better to be explicit in my opinion anyway. For what it's worth, my vote goes with the static_cast option.

As Mehrdad mentioned, use the #pragma warning syntax to disable a warning. Documentation is here - http://msdn.microsoft.com/en-us/library/2c8f766e.aspx
I would be inclined to fix the warnings rather than hide them though!

C++ has overloads for pow/powf for int exponents. Heed the warning.

Don't ignore this or any warnings. Fix them. The compiler is your friend, trying to get you to write good code. It's a friend that believes in tough love, but it is your friend.
If you have an unsigned int and need a float, convert your unsigned in to a float.
And the MSDN Library is the documentation for both the VC++ implementation of the language and the IDE itself.

Related

A lot of ambiguity errors using C++ Builder 10 Seattle

I have gotten a lot of ambiguity errors when compiling older code in the new C++ Builder 10 Seattle. For functions like log() for example.
Calling log(10) generates the following error.
[bcc32 Error] E2015 Ambiguity between 'std::log(float) at c:\program
files (x86)\embarcadero\studio\17.0\include\windows\crtl\math.h:394'
and 'std::log(long double) at c:\program files
(x86)\embarcadero\studio\17.0\include\windows\crtl\math.h:430'
Feels like it should be able to handle that conversion. A warning, fine... but an error and unable to compile? Has the compiler gotten way more strict about this with later versions? Code is originally from C++ Builder 2010.
Other ambiguity errors include void* when HWND was expected, doing things like arithmetic on TDateTimePicker->Time (->Time.Val must be used now instead) etc. This was swallowed by the compiler before but not now. I'm happy it seems to be stricter now though... But it brings with it a lot of fixes to the old code.
It's because you gave it an integer and it doesn't know what the resulting floating-point type should be. If you said log(10.0) the type defaults to double and it has no ambiguity. Just because the original integer had no suffix doesn't mean the compiler can assume you want a no-suffix version of the converted floating-point value. C++ gets a lot more picky about strong typing as the versions wear on, so this sort of insistence popping up in newer compilers isn't surprising.
NB: Just adding a suffix won't work. 10f doesn't mean it's a float. You need the decimal or the exponent (or both), also, so 10.f works and 1e1f works and 1.e1f works as well.

Passing pointer as argument c++ 2 compilers different results

I was working with another computer science student today, and he said his class was covering pointers. He was trying to understand pointers by creating an example where he was passing a pointer as an argument to a function, and setting that referenced pointer argument inside the function equal to the hypotenuse of a triangle (two of the other sides of the triangle are also passed into the function as double arguments).
As I explained to him about how pointers worked, I coached him what he should do, and we ended up with something like the example code I have below. His compiler continually failed to compile despite our efforts, but the compiler for VS2013 worked okay.
My question is simply this: Is there anything we're doing wrong with the code I've presented below? I did tell him that you'd probably use dynamic memory allocation instead of setting the pointer equal to the address of another variable we define in the program, but it seems baffling to me why the code won't compile. Same exact code, one compiles, the other doesn't. I just want to be sure the information I'm giving out is correct, of course.
And of course, much thanks to the stackoverflow community.
#include <iostream>
#include <cmath>
using namespace std;
void hypotenuse(double a, double b, double *ptr);
int main()
{
//double *ptr = new double;
double *ptr;
double c;
ptr = &c;
hypotenuse(3, 4, ptr);
cout << ptr << '\n' << *ptr;
cin.get();
}
void hypotenuse(double a, double b, double *ptr)
{
*ptr = sqrt(a*a + b*b);
}
Post was edited because we did include the cmath header, I just forgot to write it in this example because VS2013 doesn't require it. My apologies.
Both GCC and Visual C++ are conforming here. If we look to the draft C++ standard, section [res.on.headers]:
A C++ header may include other C++ headers. A C++ header shall provide
the declarations and definitions that appear in its synopsis. A C++
header shown in its synopsis as including other C++ headers shall
provide the declarations and definitions that appear in the synopses
of those other headers.
Somewhere in its standard library, Visual C++ decided to include <cmath>. From now on, follow good practice and always include headers for functions you use.
The code as posted in this question will not compile with gcc as is because it is lacking the include of the math header that defines sqrt. Your compiler error/warnings should clearly show this problem, pay close attention to those messages.
Because sqrt is not part of the c++ language you have to add an include for the cmath header. It is possible that in some iteration of your friends code you had included this header directly or indirectly however without the information about the compiler used there and an exact error message this is purely speculation, you need to include that information in a question like this to get a better answer. When you include the cmath the code will compile and run without issue.
What is the wanted result of your code?
You are calculating a hypotenuse and then
Displaying pointer's address ptr and double c's contents.
Prossible mistakes:
Omitted header for the calculations inside the function
Solution:
add header the line: #include <cmath>
I'm pretty close to closing this question. I don't think I will be able to get the compiler error message, and the question that was really being asked here was if I did anything wrong in the code that I shouldn't do. It seems to me that the answer to the question is, "Well, that depends," and it depends on the compiler; but I would like to write code that is, of course, portable.
Now, I know I've made a few small errors of bad programming practice, such as not passing by reference, forgetting to include the header for cmath, and maybe assigning a pointer to the address of an undefined variable.... and I could have made a return type instead of passing a pointer argument and so on. Although, it doesn't seem that I've done anything that should invoke the compiler error, but hey, who am I and what do I know?
I cannot get the error message from the student who compiled the code, but I believe the IDE he was using was cloud nine, an online IDE that works in browser. I don't know which version of gcc or g++ it's using, and I went to the website, signed up, and was able to compile my code just fine. I can assure you it was the same exact code I used because I took it from my email, the same code he was unable to compile on his own machine or on his own account at cloud 9.
So I think the answer to this question is that I haven't done anything that would violate the language of C++, if I can put it that way.
Anyway, just thought I'd say thanks anyway, and sorry for wasting people's time.
First off initializing a pointer without a value (double* ptr;) is bad practice and could lead to undefined behavior.
Most of the time you should not declare a void _ (T,T*) function and should instead replace the T* with a return value. This allows for return value optimizations to basically inline the functional call. It also is much more readable:
double hyp;
hypotenuse(3, 4, &hyp);
vs
double hyp = hypotnuse(3, 4);
I understand that you were teaching about pointers, but still it is much better to do an example where pointers/references make sense:
int /* error code */
getyx(int* y, int* x);
Then you can use:
int y,x;
if(getyx(&y,&x)) {
/* use value */
} else {
/* error handling */
}

Disabling "cast from pointer to smaller type uint32_t" error in Clang

I'm working on a school project that involves porting a large piece of C++ code on an experimental piece of hardware. Unfortunately, that hardware is 64-bit and the code contains many instances of pointer arithmetic that expects pointers to be 32-bit, i.e. it often does reinterpret_cast<uint32_t>(ptr).
Going through them one by one would be very tedious and since this is an experimental project anyway, I'm happy to settle for a "hackish" workaround. So instead I modified the implementation of malloc to ensure it never allocates memory above the 4GB limit. Technically, these casts should therefore be valid.
Question is, how do I explain this to Clang? The error I'm getting is: error: cast from pointer to smaller type 'uint32_t' (aka 'unsigned int') loses information. Is there a way to disable it?
Thanks,
David
I was able to disable this with -fms-extensions after getting this from someone on the Cpplang Slack:
Looking at "DiagnosticSemaKinds.td" it shows up as err_bad_reinterpret_cast_small_int, https://github.com/llvm-mirror/clang/blob/release_50/include/clang/Basic/DiagnosticSemaKinds.td#L6193
There are two occurences in "SemaCast.cpp" -- one of which suggests it's sensitive to MS extensions, https://github.com/llvm-mirror/clang/blob/release_50/lib/Sema/SemaCast.cpp#L2112
One could try -fms-extensions (hopefully not -fms-compatibility), but that would bring all the shebang with it.
I agree that you should bite the bullet and fix the code to use the correct integer type. But to answer your question: No, you can't disable it, though you can work around it.
Many errors come from warnings. A good thing in general, but if you want to disable the warning, just do it. Since the culprit is probably something like -Wall which enables many warnings you should keep on, you should selectively disable this single warning. The error message mentions the diagnostic responsible for error message, e.g. ... [-Wextra-tokens] (if it doesn't, remove the -fno-diagnostics-show-option flag). You can then disable this diagnostic completely by adding -Wno-extra-tokens (again, the "extra tokens" warning is an example), or turn it into a non-fatal warning by means of -Wno-error=extra-tokens.
However, this specific error is not due to a warning and I can't find any option to disable errors (makes sense, since most errors are fatal).
But to just truncate the integer value and not having to fix all the wrong uses of uint32_t just yet, you could use static_cast<uint32_t>(reinterpret_cast<uintptr_t>(ptr)). Needless to say, this will still be wrong.
how about using uintptr_t, most of your pointer arithmetic may still works.
Save this piece of code as mycast.hpp and add -include mycast.hpp to your Makefile.
#include <cstdint>
template<typename U, typename T>
U Reinterpret_cast(T *x) {
return (U)(uintptr_t)x;
}
template<typename U, typename T>
U Reinterpret_cast(T &x) {
return *(U*)&x;
}
#define reinterpret_cast Reinterpret_cast
They should do their job unless your code is too tricky.
Your strategy will not work for stack-allocated objects, be careful!! You can insert some debugging/logging logic to Reinterpret_cast if necessary.
I hit this same problem in a project without C++11, and worked around it like this:
inline int PtrToInt(void* ptr)
{
void* clang[1];
clang[0] = ptr;
return *(int*)clang;
}

C++ Assigning an int to a char - why does this work without at least a warning?

Why does C++ (and probably C as well) allow me to assign and int to a char without at least giving me a warning?
Is it okay to directly assign the value, like in
int i = 12;
char c = i;
i.e. do an implicit conversion, or shall I use a static_cast<>?
EDIT
Btw, I'm using gcc.
It was allowed in C before an explicit cast syntax was invented.
Then it remained a common practice, so C++ inherited it in order to not break a huge amount of code.
Actually most compilers issue a warning. If your doesn't, try change its settings.
C as originally designed wasn't really a strongly-typed language. The general philosophy was that you the programmer must know what you are doing, and the compiler is just there to help you do it. If you asked to convert between float, int, and unsigned char six or seven times in a single expression, well that must be what you wanted.
C++ sort of picked that up just so that all the existing C code wouldn't be too much of a bear to port. They are slowly trying to make it stronger with each revision though. Today just about any C++ compiler will give you a warning for that if you turn the warning levels up (which I highly recommend you do).
Otherwise, perhaps you should look into true strongly-typed languages, like Java and Ada. The equivalent Ada code would not compile without an explicit conversion.
Short answer: It's okay (by the c++ standard) in your example.
Slightly longer answer: It's not okay if char is signed and you are trying to assign it a value outside its range. It's okay if it is unsigned though (whether or not char is signed depends on your environment), then you'll get modulo arithmetics. Compilers usually have a switch to warn you because of the first case, but as long as you stay in the bounds it's perfectly fine (however, an explicit cast to make your intentions clear does not hurt).
char is the same as short. So, there should be a warning about possible lose of information. May be you have warnings switched off, try to configure somehow your compiler/ide.

Forcing an error when a function doesn't explicitly return a value on the deafult return path?

Is there a way, in VC++ (VSTS 2008), to froce a compiler error for functions that do not explicitly return a value on the default return path (Or any other quick way to locate them)?
On the same issue, is there any gaurentee as to what such functions actually return?
I don't know exactly the warning number, but you can use #pragma warning for enforcing a specific warning to be treated as error:
Example:
#pragma warning( error: 4001)
will treat warning 4001 as error
If you enable max warning level, and treat warnings as errors, you'll surely find what you're looking for. A guess as to what will be returned otherwise: A default-constructed object of the function's return type.
VC will warn about many instances of this problem, but fails to detect some. I've repeatedly caught it missing this problem in function templates, but I've seen int in some plain functions, too. Treating warnings as errors (compiler switch for all warnings or pragma for specifc ones) will make it impossible to overlook those it finds.
For those VC overlooks you have to use more thorough tools. AFAIK in VSTS you can also throw an /analyze switch for the compiler and have it find even more problems.
There's also many versions of lint-like programs.
Using some other compiler helps, too. Porting a VS project to GCC for the first time can be quite hard, but I think Intel's compiler can be used as a drop-in replacement for VC and compile VC projects right away. Comeau C++, too, has switches for being quite VC-compatible and has incredibly good errors messages.