Hi everyone.
Does anyone know how I can prevent failing in the gaps between C++ compilers?
Here are two of my experiences of this subject.
First I faced a truly amazing difference between GNU 4.7 and MS in CodeForces Round #159 (Div. 2). When the contest was running I coded a code for problem C, but it get TLE on pretest 6(been compiled by GNU 4.7). Till the end of contest I couldn't fix it. After a while, just for joke, test my code with MS and it get AC by running just for 781ms for the worst test case while the other one uses the whole 2s time limit and get TLE. It happened to me another time in another contest.**Mr.MikeMirzayanov answered : “Yes, the compilers are different. You may contact their developers :-)”**. here's the code: GNU:2891506 , MS:2893238
The second one is more exciting. One day I coded a code for problem A of CodeForces Round #165 which worked correctly for sample tests in my computer with compiler gcc 4.6.3 . I submitted it for been compiled by MS and it get compilation error (internal error). So I submitted it for been compiled by GNU 4.7 and it get WA on pretest 2(which was sample test 2). here's the code: GNU:3060066 , MS:3060060
I'm really getting confused. Can anyone help me?
Wish everyone well.
This is two different standarts of C++ language. About GNU standart you can read on http://gcc.gnu.org/ and http://cplusplus.com/. MS C++ was developed by Microsoft and you can get information about it on microsoft official webpage http://msdn.microsoft.com/en-us/library/cscc687y.aspx
Thanks. Seems I have to read about it.
There are two main things that differ between compilers (or, formally, C++ implementations):
Observable behavior. Both these compilers implement the C++98/C++03 standard, but, where the standard says the behavior is unspecified or undefined, it may be different between these compilers. The best solution to write code that behaves equivalently is to avoid invoking unspecified behavior, that is, write code that is strictly following what is guaranteed by the C++ standard itself and makes no further assumptions. An example of unspecified behavior:
char
may be either signed or unsigned, the C++ standard does not specify which one it is. Thus, if you want to have an unsigned char on every compiler, you explicitly writeunsigned char
. Writing such code requires knowledge of the C++ standard, and this comes with time. With GCC, using flags like-Wall -Wextra -pedantic -std=c++03 -O2
may help write strictly conformant code.Execution speed. Different compilers have different optimizers and may produce code that runs slower/faster than their counterparts. For the library functions, the C++ standard dictates asymptotical run time for some operations, but even in such cases doesn't say anything about the constant factor. Thus, the performance of the same conformant code between compilers may vary. Here, there probably isn't anything better than knowing how the compiler/library performs on certain operations, which again comes with experience. One notable example is the speed of the
iostreams
library in MS C++, which is several times slower than in GCC. Another example:list::size()
works in O(n) in GCC (link).However, note that during the contest you have no need to make it work with both compilers, you only need one of them. Thus you don't have to write fully portable code, you only need to write code for which you know how it behaves. But knowing how to write portable code also helps to know the peculiarities of the compiler you choose.
Regarding your examples:
In GCC,
long double
has more precision thandouble
and may be slower, while in MS C++long double
is the same asdouble
. The comparison function may have also prevented the compiler from optimizing code, as the correct way is to pass objects by reference:==
, which is not recommended). P.S. This problem can be solved without using floating point at all.Thanks a lot. Seems after 1 year coding I'm still a beginner. But I love to learn more and more.
Thank you for reading my codes. Sounds like i have to code more careful.
May I ask you why are you using GNU C++0X recently, but using GNU C++ before?
again THANKS A LOT.
"GNU C++0X" is GCC in C++11 mode. C++11 is the new C++ standard that contains many very useful features. (Codeforces is one of the few systems that provide a C++11 compiler.) You can read about new features here: http://www.stroustrup.com/C++11FAQ.html. Note that C++11 support in GCC is still incomplete.
Thanks a lot.
Seems you're really experienced in compilers.
Other thing that I saw was the difference between the explanation of deque in MS and GNU. well I got TLE on one problem in the contest but when I have used GNU instead, my time reduced to 117mls. That was Funny :))