Impossible to use C++

Write here if you have problems with your C++ source code

Moderator: Board moderators

Post Reply
DanielKO
New poster
Posts: 6
Joined: Mon Mar 13, 2006 1:07 am

Impossible to use C++

Post by DanielKO » Mon Mar 13, 2006 1:22 am

What's wrong with the judge's C++ compiler? I got a ton of Compile Error already because whatever is there compiling the C++ submissions, it doesn't accept perfectly valid C++ code. Looks like many stuffs from the standard library (cmath, iomanip, vector) aren't working properly. What's the point in accepting C++ code, if the compiler/libraries is completely broken?

There's a note in the front page saying that there's a lack of support for Java, what about including one saying that the C++ compiler doesn't work? At least people won't waste their time trying to use it.

User avatar
Krzysztof Duleba
Guru
Posts: 584
Joined: Thu Jun 19, 2003 3:48 am
Location: Sanok, Poland
Contact:

Post by Krzysztof Duleba » Mon Mar 13, 2006 2:01 am

I've been using C++ for quite some time here and I never had much trouble with OJ.

I have a few words of advice:
- don't post when too frustrated to think clearly
- learn C++ a bit more, "perfectly valid C++ code" isn't always so valid
- take into consideration that there are huge differences between compilers, if you want to get rid of CEs here you have to use gcc 2.95.
For millions of years, mankind lived just like the animals. Then something happened which unleashed the power of our imagination. We learned to talk and we learned to listen...

DanielKO
New poster
Posts: 6
Joined: Mon Mar 13, 2006 1:07 am

Post by DanielKO » Mon Mar 13, 2006 2:32 am

GCC 2.95 has a really poor support for standard C++. It would have saved much of my time if I knew this from the beginning.

And yes, I'm pretty sure my code is perfectly valid C++ (it's only 16 lines long). I compile it with -Wall -Wextra on GCC 3.4.5 and 4.0.1, Comeau accepts it, and I already checked every single line of code against ISO/IEC 14882:2003 to make sure I wasn't forgetting anything. I'm pretty sure the vector template should have an at() method (23.1.1), that the "fixed" manipulator is present in <ios> (27.4.5.4), and that ceil() is properly overloaded for the floating point types (26.5).

Now tell me how can a program generate the correct output without using iostream manipulators? Or how to control numeric aspects when ceil(), exp(), sin(), etc can't be used? You even can't use the checked access on vectors because the at() method doesn't exist.

Of course you can work around all these issues; you can write the output with printf(), write your own math functions, and add a bunch of if() tests before every operator[] acess - but this defeats the purpose in using C++ over C. It's even more troublesome to use C++ because of this.

I'm aware that there are C++ compiler that are extremely non-standard, what I don't get is why the online judge is using one of them and this isn't documented. Of course I'm frustrated; upgrading the compiler may be too much work, but posting a public notice stating that the compiler is ancient and may refuse valid code is something easy to do (and would avoid frustrating people).

User avatar
Krzysztof Duleba
Guru
Posts: 584
Joined: Thu Jun 19, 2003 3:48 am
Location: Sanok, Poland
Contact:

Post by Krzysztof Duleba » Mon Mar 13, 2006 3:05 am

gcc 3.4 is good, but not perfect.

fixed comes with <iomanip> as ios::fixed (cout.setf(ios::fixed)).

<cstdio> is not a bad choice since iostream-based IO will time out in problems with big input anyway.

I've never used ceil() before with OJ, so I don't know what are you talking about, but it should work fine, just as sin or exp.

gcc 2.95 doesn't have at() method at vector template, it's a known issue (but it's not a problem since you shouldn't use it in programming contests in the first place). If you really need it, though, implement it yourself, it's not that difficult:

Code: Select all

#include <vector>

template<typename T>
class myvectorwithat : public std::vector<T>{
    public:
    T & at(size_t idx){
        if(idx >= this -> size()){
            //do sth
        }
        return (*this)[idx];
    }
};
#define vector myvectorwithat
For millions of years, mankind lived just like the animals. Then something happened which unleashed the power of our imagination. We learned to talk and we learned to listen...

DanielKO
New poster
Posts: 6
Joined: Mon Mar 13, 2006 1:07 am

Post by DanielKO » Mon Mar 13, 2006 3:57 am

Krzysztof Duleba wrote:fixed comes with <iomanip> as ios::fixed (cout.setf(ios::fixed)).
"fixed" isn't supposed to be in <iomanip>, but in <ios> that is included by <iostream>. Try this anyways, and see if it compiles:

Code: Select all

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
        cout << fixed << 0.3 << endl;
        return 0;
}
Krzysztof Duleba wrote:<cstdio> is not a bad choice since iostream-based IO will time out in problems with big input anyway.
Really? Did gcc 2.95 had some bizarre bug related to iostreams?
Also, I don't see how can cstdio help with reading std::strings. Or are you trying to say that I should just give up std::string too? Then again, it's meaningless to try to use C++ if you can't use any C++ feature; this is my point, a half-working C++ compiler is more trouble than not using at all.
Krzysztof Duleba wrote:I've never used ceil() before with OJ, so I don't know what are you talking about, but it should work fine, just as sin or exp.
Well, sometimes you want to convert between integers and floating point types with proper rounding. I haven't looked at all problems yet, but I would be surprised if no problem requires at least a trig or rounding function. Try this code if you don't believe me:

Code: Select all

#include <cmath>

using namespace std;

int main()
{
        double x = 1
        double i = sin(x);
	return 0;
}
Krzysztof Duleba wrote:(but it's not a problem since you shouldn't use it in programming contests in the first place).
Do you mind in clarifying this? I can't see reason to not use it - other than a possible extremely poor implementation for exceptions provided by gcc 2.95. Catching an out_of_range can be much more cleaner than inserting if()s everywhere I receive an index from input.

Krzysztof Duleba wrote:If you really need it, though, implement it yourself, it's not that difficult:

Code: Select all

#include <vector>

template<typename T>
class myvectorwithat : public std::vector<T>{
    public:
    T & at(size_t idx){
        if(idx >= this -> size()){
            //do sth
        }
        return (*this)[idx];
    }
};
#define vector myvectorwithat
Thanks, but it's useless without the proper constructors, and doesn't have the same semantics. A "#define at operator[]" looks more pratical (but also breaks the semantics). Writing all the code to fix the broken library isn't feasible, so one more reason to avoid using it.

The point isn't that just "x, y and z" aren't working; the point is that it's an extremely non-conformant C++ environment, so I would bet that there are more problems like these that may affect someone that isn't aware of the issue. These are only the problems I found so far; next time the problem may be in <map>, <set>, <numeric>, <queue>, <algorithm>, etc; which of them work, and which don't? I don't want to spend 80% of the time figuring out why the compiler is refusing a perfectly valid code.

Anyways, I don't need workarounds anymore, I'll just submit my programs in C from now on; but I still think that this issue deserves at least a warning in the front page, the same way it was done for Java.

chunyi81
A great helper
Posts: 293
Joined: Sat Jun 21, 2003 4:19 am
Location: Singapore

Post by chunyi81 » Mon Mar 13, 2006 5:01 am

DanielKO wrote:

Code: Select all

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
        cout << fixed << 0.3 << endl;
        return 0;
}
Daniel, this doesn't compile with gcc 2.95, but this will:

Code: Select all

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
        cout.fixed;
        cout << 0.3 << endl;
        return 0;
}
For the code below, if you want to avoid the ambiguous method overloading error,
DanielKO wrote:

Code: Select all

#include <cmath>

using namespace std;

int main()
{
        double x = 1
        double i = sin(x);
	return 0;
}
try this:

Code: Select all

#include <cmath>

using namespace std;

int main()
{
        double x = 1;
        float f = 3.0;
        double i = sin((double)x);
        float f1 = cos((float)f);
	return 0;
}
I have no problems with the judge's C++ compiler, but the judge's C compiler in refusing to accept C++ style comments // gives me problems sometimes. And that is why I have to switched from Java, to C and then C++ in this judge. The gcc 2.95.3 compiler I have accepts C++ style // comments though, which is weird.

User avatar
Krzysztof Duleba
Guru
Posts: 584
Joined: Thu Jun 19, 2003 3:48 am
Location: Sanok, Poland
Contact:

Post by Krzysztof Duleba » Mon Mar 13, 2006 8:02 am

DanielKO wrote: "fixed" isn't supposed to be in <iomanip>, but in <ios> that is included by <iostream>. Try this anyways, and see if it compiles:
I didn't write where it's supposed to be, but where it is in gcc 2.95 and how to use it.
DanielKO wrote:
Krzysztof Duleba wrote:<cstdio> is not a bad choice since iostream-based IO will time out in problems with big input anyway.
Really? Did gcc 2.95 had some bizarre bug related to iostreams?
gcc prior to 4.0 had a really poor iostreams implementation. It was partially fixed in 3.4.
DanielKO wrote: Also, I don't see how can cstdio help with reading std::strings
You're right here, you can't do it in one instruction, you need two (read to a char * buffer and then assign it to a string).
DanielKO wrote:

Code: Select all

#include <cmath>

using namespace std;

int main()
{
        double x = 1
        double i = sin(x);
	return 0;
}
This does work as supposed. I used it hundreds of times.

return 0 is unnecessary.
DanielKO wrote: I can't see reason to not use it - other than a possible extremely poor implementation for exceptions provided by gcc 2.95. Catching an out_of_range can be much more cleaner than inserting if()s everywhere I receive an index from input.
It's just unnecessary overhead. It can be useful when you debug locally, but you will get runtime error or wrong answer if at throws exception in the judge harness (even if you catch it, you can't produce the right answer anymore, can you?).

DanielKO wrote:

Code: Select all

#include <vector>

template<typename T>
class myvectorwithat : public std::vector<T>{
    public:
    T & at(size_t idx){
        if(idx >= this -> size()){
            //do sth
        }
        return (*this)[idx];
    }
};
#define vector myvectorwithat
Thanks, but it's useless without the proper constructors, and doesn't have the same semantics.
Of course it's useless unless you finish the implementation, but it was just a hint. If you write it properly, it should have the same semantics (I can't see why not).
DanielKO wrote: Anyways, I don't need workarounds anymore, I'll just submit my programs in C from now on;
Funny you should say so.
For millions of years, mankind lived just like the animals. Then something happened which unleashed the power of our imagination. We learned to talk and we learned to listen...

DanielKO
New poster
Posts: 6
Joined: Mon Mar 13, 2006 1:07 am

Post by DanielKO » Mon Mar 13, 2006 10:14 pm

Krzysztof Duleba wrote:
DanielKO wrote:

Code: Select all

#include <cmath>

using namespace std;

int main()
{
        double x = 1
        double i = sin(x);
	return 0;
}
This does work as supposed. I used it hundreds of times.
Really? I just tested a few seconds ago, I still get a "Compile Error". Maybe you are using some magic hidden button in the Submit page that we can't see.

Krzysztof Duleba wrote:It's just unnecessary overhead. It can be useful when you debug locally, but you will get runtime error or wrong answer if at throws exception in the judge harness (even if you catch it, you can't produce the right answer anymore, can you?).
Ever heard of the magic keywords "try" and "catch"? Maybe you are thinking in using at() just to make the program crash with invalid positions, but it's also possible to simplify the code by letting the exception unwind the stack instead of verbose "if" tests. I usually don't need at(), but I was working on a problem where at() did fit perfectly; of course, I had to spend time figuring out why the OJ wasn't compiling, and when I found out, I had to write all the if tests I was trying to avoid.

Maybe I wasn't too clear in my posts so far, because I think you are missing the entire point of the discussion. We all know (at least the people who read this thread) that the C++ compiler used on the OJ is ancient and broken (considering what was said, it's GCC 2.95.2, which was released more than 6 years ago). I showed 3 examples that demonstrate how serious is the problem (if you first detect these problems in a big program, you may spend hours figuring out what's "wrong").

Of course I know how to overcome those limitations I found so far. But I don't want to spend any more time trying to avoid compiler bugs, and I bet that no C++ programmer wants to be surprised by such bugs. That's why I'm complaining, there isn't any notice about it in any visible place. In all problems I tried to solve so far, I spent more than 70% of the time fighting against the OJ's compiler. I bet that some less skilled programmer could spend even more time. And why is that? All because nobody knew that the problem is with the OJ's compiler itself, not with their code. So I think (and that's why I'm insisting) that to show a bit of consideration for people who would chose C++, a public note about the issue should be available (again, as done for Java) in the main page.

User avatar
Krzysztof Duleba
Guru
Posts: 584
Joined: Thu Jun 19, 2003 3:48 am
Location: Sanok, Poland
Contact:

Post by Krzysztof Duleba » Mon Mar 13, 2006 10:24 pm

DanielKO wrote:
Krzysztof Duleba wrote:
DanielKO wrote:

Code: Select all

#include <cmath>

using namespace std;

int main()
{
        double x = 1
        double i = sin(x);
	return 0;
}
This does work as supposed. I used it hundreds of times.
Really? I just tested a few seconds ago, I still get a "Compile Error". Maybe you are using some magic hidden button in the Submit page that we can't see.
Yes, and it's called "insert missing semicolons".
DanielKO wrote:
Krzysztof Duleba wrote:It's just unnecessary overhead. It can be useful when you debug locally, but you will get runtime error or wrong answer if at throws exception in the judge harness (even if you catch it, you can't produce the right answer anymore, can you?).
Ever heard of the magic keywords "try" and "catch"?
Now you're being impolite and obviously you can't read as well, I guess I'm just going to ignore you from now on.
DanielKO wrote: Maybe I wasn't too clear in my posts so far, because I think you are missing the entire point of the discussion. We all know (at least the people who read this thread) that the C++ compiler used on the OJ is ancient and broken (considering what was said, it's GCC 2.95.2, which was released more than 6 years ago). I showed 3 examples that demonstrate how serious is the problem (if you first detect these problems in a big program, you may spend hours figuring out what's "wrong").
The thing I'm trying to do is to help you to have your code accepted in C++, but you can't see it, can you? The judge software is as it is and there's little hope for change.
For millions of years, mankind lived just like the animals. Then something happened which unleashed the power of our imagination. We learned to talk and we learned to listen...

DanielKO
New poster
Posts: 6
Joined: Mon Mar 13, 2006 1:07 am

Post by DanielKO » Mon Mar 13, 2006 10:44 pm

Krzysztof Duleba wrote:Yes, and it's called "insert missing semicolons".
Ouch. Ok, this one works, my mistake.

Krzysztof Duleba wrote:Now you're being impolite and obviously you can't read as well, I guess I'm just going to ignore you from now on.
You weren't too polite either from the begining, assuming that I should learn more before pointing real problems present in the compiler. You were again, assuming that I don't know how to use exceptions. I just said that maybe you use them differently from the way I do (considering your comment "even if you catch it, you can't produce the right answer anymore, can you?").

Krzysztof Duleba wrote:The thing I'm trying to do is to help you to have your code accepted in C++, but you can't see it, can you? The judge software is as it is and there's little hope for change.
I'm sorry for misunderstanding you then. I didn't demand an upgrade in the judge software, just asked for a public notice about the problem (or at least some information about the compiler used), or more people will just fall in the same traps.

david
Learning poster
Posts: 83
Joined: Mon Apr 21, 2003 10:14 pm

Post by david » Wed Mar 15, 2006 1:05 pm

You're talking nonsense. ceil(), sin, exp().. all work perfectly, as does everything I have tried using from the STL, for instance. You are still to provide an example of a problem with the judge compiler.

DanielKO
New poster
Posts: 6
Joined: Mon Mar 13, 2006 1:07 am

Post by DanielKO » Wed Mar 15, 2006 10:07 pm

david wrote:You're talking nonsense. ceil(), sin, exp().. all work perfectly, as does everything I have tried using from the STL, for instance. You are still to provide an example of a problem with the judge compiler.
You are probably too busy to read the whole thread (but unfortunatelly not enough to keep you from posting on it), so I'll make a resume for you:
I admited already that I was indeed mistaken about cmath functions. I provided 2 other examples that are legitimate programs and the OJ still refuses them. It was suggested that the compiler used is GCC 2.95.2 or earlier; I could go after all GCC 2.95.2 bugs, test each one agains the OJ, and show you all that didn't compile (but that would not only be useless as you didn't test the other 2 that I mentioned in this thread, but also pointless as it won't change anything). This discussion already ended, but if you want to go further, I would recommend to go to comp.lang.c++.moderated and try to defend GCC 2.95.2 as a suitable C++ compiler.

chunyi81
A great helper
Posts: 293
Joined: Sat Jun 21, 2003 4:19 am
Location: Singapore

Post by chunyi81 » Thu Mar 16, 2006 7:45 am

Daniel, I noticed that you had to use at function of vector class to access a vector element. Do you know that you can use the [] operator for vectors in place of at function?

User avatar
Krzysztof Duleba
Guru
Posts: 584
Joined: Thu Jun 19, 2003 3:48 am
Location: Sanok, Poland
Contact:

Post by Krzysztof Duleba » Thu Mar 16, 2006 5:02 pm

I'm pretty sure he knows that.
For millions of years, mankind lived just like the animals. Then something happened which unleashed the power of our imagination. We learned to talk and we learned to listen...

Post Reply

Return to “C++”