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

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.

Related

Problems compiling and executing this code in C++

I'm trying to compile this code in TurboC++ 3.0. However, I got these errors:
DOS.H 77: Too many types in declaration
DOS.H 77: { expected
DOS.H 77: Declaration does not specify a tag or an identifier
SARSAL.CPP 72: Cannot cast from 'int' to 'time'
I checked the directories of the libraries and I have run the code in BorlandC++ 5.02 (unfortunately, I get the graphics error or this error: Constructor cannot have a return type specification, in the method void Agente::Agente), DevC++ and Code::Blocks without success.
The code was provided by our AI teacher and supposedly works fine. How do I get it to compile?
Thanks for the help.
I normally wouldn't answer this kind of post (and not just because of the "TurboC++" issue) but we were all newbies at some point and needed help but didn't know how to ask for it, so I'll give you a hand.
First and foremost: DON'T USE TurboC++. As others have said, it's ancient and will require you to learn a language that's very different than the C++ of today and will teach you many many bad habits (e.g. #include <iostream.h> which is wrong).
With that out of the way, let's get started, shall we?
You define a constructor (around line 70) and give it a return type of void. This is wrong: constructors don't have return types. The correct syntax is:
Agente::Agente(void)
{
randomize();
}
Perhaps TurboC++ requires a return type (see?) or perhaps this was just your mistake, but either way, this is a bug because that is not C++ code.
Moving forward, you have this on line 127:
if((Archivo = fopen("C:\Documents and Settings\ArCiGo\Escritorio\SOFTWARE_2\DATOS.TXT","r"))!=NULL)
The character \ is special in C++ (e.g. \n represents a newline and \x01 is the character with value 1.
If you want to use it, you must escape it with another \ like this:
if((Archivo = fopen("C:\\Documents and Settings\\ArCiGo\\Escritorio\\SOFTWARE_2\\DATOS.TXT","r"))!=NULL)
There are other places where you do the same thing. Fix those and try again. I bet that you will have a lot better luck and fewer errors to worry about.
For future reference, when you are looking for help try to post a SHORT, self-contained program that exhibits the error that you are getting, so that others don't need to wade through hundreds of lines of code and worry about missing header files and platform-specific differences.

gfortran - assign string to parameter

[NOTE: contains repetition of previous question but posted separately as separate issues]
I am compiling a program which is known to compile with ifort using gfortran. However the compiler fails on the line
PARAMETER (POS='^')
with the compile error:
conv_prof.mac:9.21:
Included at conv_prof.f:811:
PARAMETER (POS='^')
1
Error: Can't convert CHARACTER(1) to REAL(4) at (1)
make: *** [conv_prof.o] Error 1
As it turns out the POS parameter is not used (it is likely a legacy parameter) so I may simply uncomment this line to compile, but I would like to know if anyone might have any idea why this is an issue in gfortran and not ifort?
Cheers,
Derek
The Intel compiler is the descendant of a long line of Fortran compilers. Its ancestors implemented all sorts of non-standard behaviour and, in the true spirit of Fortran, the latest versions of the compiler ought to compile the most ancient codes. You can often tell ifort to warn of non-standard features in your codes by judicious use of compiler flags.
gfortran, on the other hand, does not (by default) accept much in the way of non-standard syntax, other than those forms of non-standard syntax which have been so widely used that many unsuspecting programmers think that they are standard forms (eg real*4 and the like).
Your snippet looks to me to come from the days prior to FORTRAN77 when the language didn't really acknowledge the existence of such new-fangled ideas as non-numeric variables. In this case I recommend that you follow gfortran in disallowing this code, rather than Intel Fortran.
The specific extension here is that ifort allows a program to "assign" a character value into a real object. Perhaps it was intended to use this extension - but a more likely explanation is that a type declaration statement for the parameter pos is missing prior to the PARAMETER statement.
Technically I don't think the standard requires a diagnostic in this case (this isn't a violation of the syntax rules or constraints of the standard - it is a violation of the requirements placed on the program in the body text), but you'll get a diagnostic from ifort if you turn on standards checking (/stand or -stand, depending on your platform).

boost::bind doesn't work in VC++ 2010 when binding a function that throws exceptions

I have some code which compiles fine under Linux, but I am trying to port it to Windows. I have used the Boost 1.50 precompiled binaries from Boost Pro, but when I compile my code I get this cryptic error:
error C2664: 'boost::_bi::bind_t<R,F,L>::bind_t(const boost::_bi::bind_t<R,F,L> &)' :
cannot convert parameter 1 from 'boost::_bi::bind_t<R,F,L>'
to 'const boost::_bi::bind_t<R,F,L> &'
C:\Program Files (x86)\boost\boost_1_50\boost\bind\bind_cc.hpp [line] 50
The error is most unhelpful because it shows up deep in the Boost header files, with no indication of where in my code the problem is. Nevertheless by commenting out various blocks of code I have narrowed it down to this as the cause:
void test(int a)
throw (int) // removing this line makes it compile
{
return;
}
...
boost::function<void(int)> fn = boost::bind<void>(test, _1);
It works if I remove the throw specifier in the function definition. It doesn't matter what I throw, whether it's a class or just an int. Am I doing something wrong, or can't you bind to functions that throw exceptions in Visual C++? The Boost Bind docs don't seem to suggest any issues with this, and GCC doesn't have a problem with it either way.
[Side note: The code above is not my actual code, but when compiled it exhibits the same problem. Please avoid comments about throwing ints being bad and the like, as this is only supposed to be a trivial example in case anyone wishes to reproduce the problem.]
I don't know why your code fails on VC++. However, in general exception specifications are best avoided because they can introduce very subtle effects. See this excellent column A Pragmatic Look at Exception Specifications by Herb Sutter:
So here’s what seems to be the best advice we as a community have
learned as of today:
Moral #1: Never write an exception specification.
Moral #2: Except possibly an empty one, but if I were you I’d avoid
even that.

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.

VC++ compiler and type conversion?

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.