The difference between G ++ and C ++ when OJ is submitted.

Source: Internet
Author: User

[Switch] the difference between G ++ and C ++ when submitting OJ, oj
About G ++

First of all, let's look at the concept that C ++ is a computer programming language. G ++ is not a language, but a command for compiling C ++ programs in a compiler. So what is the difference between them?

In the language options for submitting a question, both G ++ and C ++ represent the compilation method. To be accurate, selecting C ++ means that you will use the most standard compilation method, that is, ansi c ++ compilation. If you are using G ++, it means that you will use the most common applicable compiler in the GNU project (in fact, we are familiar with the Code: Blocks's built-in compiler, in Windows, gcc under MinGW is generally used, and gcc in Linux is basically the same as the former) for compilation. Similarly, C and GCC are selected. The former is compiled by the Standard C compiler, and the latter is compiled by gcc.

Differences in compilers-Compiler Optimization

Of course, many times some of our code is submitted through C ++, but G ++ fails? As we all know, different compilers will make different Optimizations to the code. The simplest example is as follows. For a single statement (Note: it is a single statement, not the prefix ++ and suffix ++ contained in the statement ):

 
12 A: a ++; B: ++;

Generally speaking, we all know that the final results of these two statements are the same, that is, a increases by 1. However, there are still some gaps between the two. From the perspective of Standard C. The a ++ statement is equivalent

 
1 A: a = a + 1

That is to say, I first call and then auto-increment. During the call process, a new data address will be requested to store the temporary variable A'. Then, after adding a' to 1, the' will be assigned to. However, the statement ++ a does not need to be so troublesome. Because it is self-incrementing first and then called, which saves the effort to apply for a new address. Therefore, theoretically, there is a difference in time consumption between the two. If you use the standard C compilation method, you can find this difference. After all, it takes much longer to apply for temporary memory than to change the data in known memory. But the optimization of the compiler is reflected in the difference between the same results but time-consuming. If you use gcc for compilation, you will find that there is basically no difference between ++ and ++. This is the tip of the iceberg in Compiler optimization. There are actually many optimizations.

Why did G ++ submit WA?

Let's get back to reality. I encountered the embarrassing situation of G ++ WA and C ++ AC when I was doing the poj 3122 question yesterday. Why? In fact, this is part of Compiler optimization, that is, the default accuracy.

As we all know, the long type is a data type that is recognized as a basic data type only in C/C ++ 11. In different environments, its type identifier is different. That is, % lld and % I64d. Similarly, the double type is also an interesting type. The double type is actually a double-precision type. Its memory length is generally twice that of the float type (single-precision type, sometimes double is called long float in a very early standard. So we can see why the float type uses % f and the double type uses % lf. However, since it is not the previous time that a memory stick is only a few megabytes, opening a double will overwrite the memory, so double and float will be automatically optimized in gcc.

% Lf is used to distinguish it from float when scanf is used to read data.

When using printf to write data, because in essence, double and float are of the same type, but the memory usage is different. Their identifiers are both % f. Note that this is different from standard C, % f is used here.

Of course, it is not commonly used for another special type long double, but it is still supported by the compiler. Here is an episode, in theory, long double should be double (similar to the relationship between long and int, because long and int are actually one thing ).

But in fact, the strange thing about long double is a 10-byte monster. He has two spare bytes, so no change will happen. The input and output identifiers are both % Lf and uppercase L.

 

But there is another problem here. Why do I use % f locally to access WA and use % f to access AC on OJ?

Because if we use the IDE Code: Blocks in Windows, the compiler is MinGW. In fact, in order to keep gcc cross-platform as much as possible, MinGW directly uses MSVC in some places, and the most influential to us is the identifier problem. To put it simply, if you want to test it on the local machine, use the identifier system of standard C. If you want to submit code, change it to the gcc identifier system. There is also a problem with the compiler version. Now the MinGW version has reached 4.8, but the POJ still makes 4.4, so the earlier version of the compiler will also have some unusual problems.

Of course, there is also a simpler method, that is, directly using the input and output stream to control the input and output, which is easier, and provides better cross-platform performance, so there will be no such error due to identifiers.

This is what a table is like:

Double f; Poj g ++ submit Poj c ++ submit Local testing (MinGW GCC 4.8) The safest way
Input Scanf ("% lf", & f ); Scanf ("% lf", & f ); Scanf ("% lf", & f ); Cin> f;
Output Printf ("% f", f ); Printf ("% lf", f ); Printf ("% lf", f ); Cout <f;

This is probably the case. I hope you can avoid this kind of error.

 

---------------------------------------------------------------- The above content is reprinted -----------------------------------------------------------------------

 

Add... cin and cout are relatively safe in this regard, but the reading speed is much slower than that of scanf and printf. In ACM competitions, using cin and cout may lead to TLE,

In fact, there is a reason for the slow cin. By default, cin and stdin are always synchronized. That is to say, these two methods can be mixed without worrying about file pointer confusion, the same is true for cout and stdout. This compatibility feature causes many additional overhead for cin. How can I disable this feature? You only need one statement std: ios: sync_with_stdio (false); To cancel synchronization of cin to stdin.

std::ios::sync_with_stdio(false);std::cin >> n;
std::cout << n;

The speed can basically reach csanf and printf.

 

Hope to help ~ Thank you.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.