S.HASHEMI's blog

By S.HASHEMI, 12 years ago, In English

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.

  1. 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

  2. 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.

  • Vote: I like it
  • +2
  • Vote: I do not like it

»
12 years ago, # |
Rev. 2   Vote: I like it +3 Vote: I do not like it

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

»
12 years ago, # |
Rev. 2   Vote: I like it +11 Vote: I do not like it

There are two main things that differ between compilers (or, formally, C++ implementations):

  1. 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 write unsigned 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.

  2. 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:

  1. In GCC, long double has more precision than double and may be slower, while in MS C++ long double is the same as double. The comparison function may have also prevented the compiler from optimizing code, as the correct way is to pass objects by reference:

    inline LD angle(const point& p)
    {
        return atan2(p.Yp,p.Xp);
    }
    
    inline bool com(const point& p1, const point& p2)
    {
        return angle(p1)<angle(p2);
    }
  2. Internal compiler error always means a bug that should be reported to compiler's developers. For the GCC case, note how many floating point operations are there; it may be the accumulated precision loss that causes the incorrect answer to be printed (and you also compare floats with ==, which is not recommended). P.S. This problem can be solved without using floating point at all.
  • »
    »
    12 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    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.

    • »
      »
      »
      12 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      "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.

      • »
        »
        »
        »
        12 years ago, # ^ |
          Vote: I like it +1 Vote: I do not like it

        Thanks a lot.

        Seems you're really experienced in compilers.

»
12 years ago, # |
  Vote: I like it 0 Vote: I do not like it

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 :))