-
March 20th, 2012, 08:08 PM
#1
Xcode 4 C++ not compiling
I'm taking an intro to c++ class and during an exercise I ran into multiple errors that are out of my knowledge to fix. The rest of the class is using Visual and that is all the instructor knows so i'm in my own figuring out Xcode. Basically I wrote the same program twice but one has a different struct and I get all sorts of errors with it. I was hoping someone could help me understand what the errors are and why they occurred.
The working program is this:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
using namespace std;
struct point
{
public:
double x1,y1;
double x2,y2;
};
double distance(point);
int main (int argc, const char * argv[])
{
point point;
double dist;
ifstream infile("/Value.txt");
ofstream ofile("/Output.txt");
ofile<<" X1 Y1 X2 Y2 Distance\n";
ofile<<" --- --- --- --- --------\n";
ofile<<fixed;
ofile<<showpoint;
ofile<<setprecision(2);
do
{
infile>>point.x1>>point.y1>>point.x2>>point.y2;
dist = distance(point);
ofile<<setprecision(1);
ofile<<setw(4)<<point.x1;
ofile<<setw(7)<<point.y1;
ofile<<setw(7)<<point.x2;
ofile<<setw(7)<<point.y2;
ofile<<setprecision(2);
ofile<<setw(11)<<dist<<endl;
} while (!infile.eof());
infile.close();
ofile.close();
return 0;
}
double distance(point point)
{
double d;
d=sqrt(pow(point.x2-point.x2, 2)+pow(point.y2-point.y1, 2));
return d;
}
Now when I change the struct to how the teacher wants it the program looks like:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
using namespace std;
struct point
{
public:
double x,y;
};
double distance(point, point);
int main (int argc, const char * argv[])
{
point one, two;
double dist;
ifstream infile("/Value.txt");
ofstream ofile("/Output.txt");
ofile<<" X1 Y1 X2 Y2 Distance\n";
ofile<<" --- --- --- --- --------\n";
ofile<<fixed;
ofile<<showpoint;
ofile<<setprecision(2);
do
{
infile>>one.x>>one.y>>two.x>>two.y;
dist = distance(one, two);
ofile<<setprecision(1);
ofile<<setw(4)<<one.x;
ofile<<setw(7)<<one.y;
ofile<<setw(7)<<two.x;
ofile<<setw(7)<<two.y;
ofile<<setprecision(2);
ofile<<setw(11)<<dist<<endl;
} while (!infile.eof());
infile.close();
ofile.close();
return 0;
}
double distance(point one, point two)
{
double d;
d=sqrt(pow(two.x-one.x, 2)+pow(two.y-one.y, 2));
return d;
}
This program does not compile and I get the following errors:
stl_iterator_base_types.h
1) Symantic Issue
No type named 'value_type' in 'myPoint'
2) Symantic Issue
No type named 'iterator_category in 'myPoint'
3) Symantic Issue
No type named 'difference_type' in 'myPoint'
4) Symantic Issue
No type named 'pointer' in 'myPoint'
5) Symantic Issue
No type named 'reference' in 'myPoint'
Why does one work and the other doesn't!? This is more than frustrating.
-
March 20th, 2012, 11:19 PM
#2
Re: Xcode 4 C++ not compiling
1) Please use code tags when posting code.
Code:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
using namespace std;
struct point
{
public:
double x,y;
};
double distance(point, point);
int main (int argc, const char * argv[])
{
point one, two;
double dist;
ifstream infile("/Value.txt");
ofstream ofile("/Output.txt");
ofile<<" X1 Y1 X2 Y2 Distance\n";
ofile<<" --- --- --- --- --------\n";
ofile<<fixed;
ofile<<showpoint;
ofile<<setprecision(2);
do
{
infile>>one.x>>one.y>>two.x>>two.y;
dist = distance(one, two);
ofile<<setprecision(1);
ofile<<setw(4)<<one.x;
ofile<<setw(7)<<one.y;
ofile<<setw(7)<<two.x;
ofile<<setw(7)<<two.y;
ofile<<setprecision(2);
ofile<<setw(11)<<dist<<endl;
} while (!infile.eof());
infile.close();
ofile.close();
return 0;
}
double distance(point one, point two)
{
double d;
d=sqrt(pow(two.x-one.x, 2)+pow(two.y-one.y, 2));
return d;
}
See how this looks?
Second, the way you figure out compiler errors is to comment out your code until you get no errors. Then you reintroduce the lines you commented out to see which line gives the problem.
If you did that, then you would have seen that this is the first error:
Code:
dist = distance(one, two);
The error is that there is a std:istance() function already existing in the C++ library, and you went ahead and created your own distance() function, conflicting with the already defined function. The compiler gets confused, thinking you're trying to call the std:istance() function instead of your own version of distance().
There are several fixes:
1) Give your function a different name than "distance", or
2) Tell the compiler which distance() function it's supposed to consider. You can do that by specifying that the function resides in the global namespace:
Code:
dist = ::distance(one, two);
This tells the compiler to look at the global distance() function (your function) instead of std:istance().
The moral of the story is try to refrain from using names of variables and functions that happen to match names already specified in the C++ library. For examples variables or functions named "list", "set", "array", "distance", "map", etc. can get you in trouble, since they are all classes and functions described in the C++ library.
I know that you're a beginner, but if you personally use names that sound too common, i.e. "list" or "distance", then be aware of problems like this.
Regards,
Paul McKenzie
-
March 21st, 2012, 10:03 AM
#3
Re: Xcode 4 C++ not compiling
Also note that the statement
Code:
using namespace std;
masked the issue. If you removed that line and used scope resolution, your distance funtion would have ben called instead of the one in std.
"Effective teaching is the essence of leadership..."
"There is no substitute for a carefully thought-out design."
If you have found this post to be useful, please Rate it.
-
March 21st, 2012, 12:15 PM
#4
Re: Xcode 4 C++ not compiling
I'm a bit confused here actually on my end:
Isn't the compiler supposed to choose the non-template distance over the template distance? Furthermore, isn't the compiler supposed to notice that the template doesn't work, and keep looking for an alternative (eg SFINAE)?
I was going to say it could be a scope issue (the compiler stops searching outside of namespace std once it finds the first match), but I get the same errors when declaring the distance method inside namespace std...?
Using C++11 (MinGW 4.6.2), the code compiles fine...
Does anybody know what rules changed exactly?
Last edited by monarch_dodra; March 21st, 2012 at 12:18 PM.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
March 21st, 2012, 01:13 PM
#5
Re: Xcode 4 C++ not compiling
>> Isn't the compiler supposed to choose the non-template distance over the template distance?
yes, but all candidates for overload resolution must be legal ( with the expception of a deduction failure, but see below )
>> Furthermore, isn't the compiler supposed to notice that the template doesn't work, and keep looking for an alternative (eg SFINAE)?
SFINAE is not triggered by all kind of errors; it must be an error occurring during type deduction and it must be "relative to the to be inspected expression only" ( sorry, I don't remember the exact rule ).
In this case, std:istance matches ok because iterator_traits<T>:ifference_type is defined for every T, so no deduction failure occurs ( it's T:ifference_type that is not defined ).
>> Using C++11 (MinGW 4.6.2), the code compiles fine...
now, this is surprising ! I recall that there was a proposal to change the SFINAE "sensitivity" in c++11, but I don't think it would apply here ...
indeed, note that in vc2010 the code does not compile as expected.
Last edited by superbonzo; March 21st, 2012 at 01:45 PM.
Reason: replaced "substitution error" with "deduction failure"
-
March 21st, 2012, 01:22 PM
#6
Re: Xcode 4 C++ not compiling
Originally Posted by superbonzo
indeed, note that in vc2010 the code does not compile as expected.
The OP's original code doesn't compile with Comeau C++ due to wrong distance() function being called.
There is a further error when compiling using Comeau, that "pow" is ambiguous.
Regards,
Paul McKenzie
-
March 21st, 2012, 01:30 PM
#7
Re: Xcode 4 C++ not compiling
Originally Posted by superbonzo
>> Isn't the compiler supposed to choose the non-template distance over the template distance?
yes, but all candidates for overload resolution must be legal ( with the expception of a deduction failure, but see below )
But in this case, the overload is legal, so what gives?
Originally Posted by superbonzo
>> Using C++11 (MinGW 4.6.2), the code compiles fine...
now, this is surprising ! I recall that there was a proposal to change the SFINAE "sensitivity" in c++11, but I don't think it would apply here ...
indeed, note that in vc2010 the code does not compile as expected.
Well, in my eyes, the code is legal to begin with, and the compiler shouldn't even be trying to use template std:istance...
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
March 21st, 2012, 01:39 PM
#8
Re: Xcode 4 C++ not compiling
Code:
do
{
infile>>one.x>>one.y>>two.x>>two.y;
//... process values
} while (!infile.eof());
This code will behave strangely if you are not able to read all 4 values from the file, and may appear to process the last set of data twice. I recommend this instead:
Code:
while (infile>>one.x>>one.y>>two.x>>two.y)
{
//... process values
}
It is usually best to avoid predicating loops on checks to eof().
-
March 21st, 2012, 01:42 PM
#9
Re: Xcode 4 C++ not compiling
-
March 21st, 2012, 01:45 PM
#10
Re: Xcode 4 C++ not compiling
I think what monarch is confused about is why the compiler is bothering to try the substitution at all, given that it has a matching non-template function available which it is supposed to prefer.
-
March 21st, 2012, 01:49 PM
#11
Re: Xcode 4 C++ not compiling
Possibly the reason has to do with whether the namespace in the using clause is searched first for a match. Since there is
Code:
using namespace std;
does this override the global namespace search? If so, then the compiler will see std:istance() first, thus give the error, without considering the global namespace. This is just a guess, so I am not sure.
Note that the error was fixed when the global namespace/scope resolution operator is used in the call to distance.
Regards,
Paul McKenzie
-
March 21st, 2012, 02:08 PM
#12
Re: Xcode 4 C++ not compiling
Originally Posted by Lindley
I think what monarch is confused about is why the compiler is bothering to try the substitution at all, given that it has a matching non-template function available which it is supposed to prefer.
Originally Posted by n3242
If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed if written using the substituted arguments. Access checking is not done as part of the substitution process. Consequently, when deduction succeeds, an access error could still result when the function is instantiated. Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure. [Note: The evaluation of the substituted types and expressions can result in side e?ects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-de?ned functions, etc. Such side effects are not in the “immediate context” and can result in the program being ill-formed.—end note ]
The compiler is required to collect all possible candidates for overload resolutions. When a template candidate is found, type deduction occurs. Type deduction fails whenever there is a substitution error. Such an error can be ignored when it involves just "invalid types and expressions in the immediate context of the function type and its template parameter types"; otherwise an error occurs.
To my understanding, this is exactly what happens when the compiler finds the std:istance overload pulled in by the using directive ( the order is not an issue here ); indeed, it fails to compile on comeau,vc2008 and vc2010; now, given that all three of them have no or limited c++11 support, I'm not sure on how to interpret the MinGW 4.6.2 behavior ... my bet is that it's non-standard
-
March 21st, 2012, 02:17 PM
#13
Re: Xcode 4 C++ not compiling
does this override the global namespace search? If so, then the compiler will see std: istance() first, thus give the error, without considering the global namespace. This is just a guess, so I am not sure.
This has always been my understanding of the using clause. It is the reason the last 2 places where I worked restricted its use because it frequently caused this type of an issue.
"Effective teaching is the essence of leadership..."
"There is no substitute for a carefully thought-out design."
If you have found this post to be useful, please Rate it.
-
March 21st, 2012, 04:40 PM
#14
Re: Xcode 4 C++ not compiling
Originally Posted by superbonzo
The compiler is required to collect all possible candidates for overload resolutions. When a template candidate is found, type deduction occurs. Type deduction fails whenever there is a substitution error. Such an error can be ignored when it involves just "invalid types and expressions in the immediate context of the function type and its template parameter types"; otherwise an error occurs.
To my understanding, this is exactly what happens when the compiler finds the std: istance overload pulled in by the using directive ( the order is not an issue here ); indeed, it fails to compile on comeau,vc2008 and vc2010; now, given that all three of them have no or limited c++11 support, I'm not sure on how to interpret the MinGW 4.6.2 behavior ... my bet is that it's non-standard
Thanks for the explanation!
On a interesting note, adding the typedefs to Point allows the code to compile, and using the debugger, I can confirm that the correct (non-template) function is indeed called.
Nice catch.
[EDIT]Couldn't give you any reputation
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
March 22nd, 2012, 12:03 PM
#15
Re: Xcode 4 C++ not compiling
After digging really deep into the code, I realized that GCC's C++11 code, uses:
Code:
_GLIBCXX_HAS_NESTED_TYPE(iterator_category)
template<typename _Iterator,
bool = __has_iterator_category<_Iterator>::value>
struct __iterator_traits { };
So long story short, given the implementation, SFINAE can legally occur, hence the template is ignored, and only the non-template function remains as a valid function.
So it is not a bug in the core compiler, rather a non-standard implementation of the library... Edit: Is it, non standard, or does the implementation allow some leeway on the implementation of the traits classes?
Last edited by monarch_dodra; March 22nd, 2012 at 12:33 PM.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|