Блог пользователя ExpectoPatronum

Автор ExpectoPatronum, история, 3 года назад, По-английски

Today in contest cf round 749, I have FST in problem C (WA on test 16 in C++20) 132242048. After contest I have no change in my code and I submit in C++17 (WA on test 19) 132266690 and in C++14 and got accepted 132266932. What is the magic here ! Pls explain to me ! Thanks.

  • Проголосовать: нравится
  • +15
  • Проголосовать: не нравится

»
3 года назад, # |
Rev. 2   Проголосовать: нравится +48 Проголосовать: не нравится

You have undefined behaviour in your code

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится

    I know my mistake is I defined an array locally and did't initialize it but why C++14 accept my code. Is C++14 have something difference when used a locally array ?

    • »
      »
      »
      3 года назад, # ^ |
        Проголосовать: нравится +30 Проголосовать: не нравится

      The compiler is different. I doubt standard has something to do with it.

    • »
      »
      »
      3 года назад, # ^ |
        Проголосовать: нравится +8 Проголосовать: не нравится

      but why C++14 accept my code

      It's literally called "undefined behavior": I suppose there isn't really a way to explain how. Your best bet is to avoid writing codes with undefined behaviors.

»
3 года назад, # |
  Проголосовать: нравится -31 Проголосовать: не нравится

c++14 is old and you know old is 'gold'.

»
3 года назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

I compiled your code on my personal computer using GNU++20 with all warnings turned on. The following is the only warning which the compiler reported.

E:\CPP\Omkar and Determination\main.cpp: In function 'void Solve()':

E:\CPP\Omkar and Determination\main.cpp:49:10: warning: ISO C++ forbids variable length array 'a' [-Wvla]

   49 |     char a[n + 2][m + 2];

      |          ^

E:\CPP\Omkar and Determination\main.cpp:49:10: warning: ISO C++ forbids variable length array 'a' [-Wvla]

I replaced the variable length array declaration and initialization with the following declaration

    using cvector = vector<char>;
    using cmatrix = vector<cvector>;
    cmatrix a(n+2,cvector(m+2,0));

And your updated code was accepted when submitted to the GNU++20 compiler at Codeforces.

132300063

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    What is the compilation code to get all warnings ?

    • »
      »
      »
      3 года назад, # ^ |
      Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

      I used the following Warning Options

      -Wall -Weffc++ -Wextra -Wpedantic -Wnon-virtual-dtor -Wshadow -Winit-self -Wredundant-decls -Wcast-align -Wundef -Wfloat-equal -Winline -Wunreachable-code -Wswitch-enum -Wmain  -Wmissing-include-dirs
      

      Check the following link for more details.

      G++ Warning Options

      • »
        »
        »
        »
        3 года назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Can you guide me to setup these compilation flags in VS Code (minGW compiler) ??

        • »
          »
          »
          »
          »
          3 года назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Check the information provided in the following link.

          Using GCC with MinGW

          You need to update the "args" line in the tasks.json file to add these options to the arguments passed to the g++ compiler.

»
3 года назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

Is C++20 backwards compatible? Like I'll be able to compile any code intended for C++17 without any warnings/errors?

Also, what more does it have to offer? E.g. for (auto [a,b] : c) this kind of decomposition was only introduced in newer versions of C++ if I'm not mistaken.

  • »
    »
    3 года назад, # ^ |
    Rev. 4   Проголосовать: нравится 0 Проголосовать: не нравится

    In general, backward compatibility is fundamental software engineering requirement in programming language development. The answer to your first question is: it should be possible to compile and run successfully "most" older c++ programs that were written for C++17. In few cases, some features in earlier versions are deprecated and not supported in the latest language version. The compiler documentation should provide sufficient information about such features.

    RE: your second question

    Check the following link for new language features in C++20.

    C++20

    • »
      »
      »
      3 года назад, # ^ |
        Проголосовать: нравится +8 Проголосовать: не нравится

      This is well and good, but I asked here so that I get to know the features prominent from competitive programming perspective, instead of reading the entire documentation :D

      • »
        »
        »
        »
        3 года назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Check the "Removed features and deprecation" section in the following Wikipedia page.

        C++20

        From competitive programming perspective, I do not think using C++20 would produce so many backward incompatibility issues when older programs intended for C++17 are resubmitted.

        Nonetheless, I recommend compiling programs locally with all warning options enabled before submitting it to the automatic judge, so as to avoid situations like the one reported in this blog. Note that the automatic judge reports compilation errors only, and ignores all warnings.

»
3 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

did U submit code after change (AC code ) in C++20 ?

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Yes, I checked the updated code after fixing the warning.

    132300063

    I usually do not ignore any compilation warning, and try to make sure that the submitted code is warning-free with respect to the available g++ compiler warning options.

    • »
      »
      »
      3 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Fine , This means that the problem is in C++17 ?

      • »
        »
        »
        »
        3 года назад, # ^ |
        Rev. 6   Проголосовать: нравится 0 Проголосовать: не нравится

        Not in the C++ language version 2017, but the issue is in the GNU++17 compiler when allocating local memory space for variable-length array which ISO C++ standard forbids.

        Note that the C++ compiler allocates enough memory size in the program stack for local variables inside a code block. This space is allocated by decreasing the stack pointer of the process by the required amount, and is de-allocated after executing the code block by restoring the stack pointer to its previous value before entering the block, provided that this memory size is known at compile-time. When dealing with variable-length arrays, the compiler does not have information about the exact size of the array. Therefore, the compiler should have dealt with the variable-length array declaration which violated ISO C++ standard by implicitly calling dynamic memory management library functions.

        • »
          »
          »
          »
          »
          3 года назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          The issue is not with the "variable-length array" at all. The author declared an array in line 50 char a[n + 2][m + 2] but didn't initialize it. As a result, there were garbage values in the array which raised undefined behavior.
          Just initialize the array with the null character '\0'. You will get AC in every compiler.

          • »
            »
            »
            »
            »
            »
            3 года назад, # ^ |
            Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

            Well, this sounds logical. But, the GNU++20 submission which failed on test 16 had the two-dimensional array initialized.

            I double checked the submission before replacing the three lines 49-51 with:

                using cvector = vector<char>;
                using cmatrix = vector<cvector>;
                cmatrix a(n+2,cvector(m+2,0));
            

            The same issue persists even with the variable-length array initialized.

            132386103

            132386200

            Update:

            I have just noticed the issue with the variable-length initialization which failed on test 16.

            132386542

            The double-loop in lines 50 and 51 should have started with i = 0 and j = 0 to initialize the first row and the first column properly.

            It seems that the implicit dynamic memory allocation library function call in GNU++14 initialized the first row and the first column of the variable-length array implicitly to 0, while the same library function call in GNU++20 did not initialize the allocated memory.

            Only the first row and the first column were uninitialized in the original code. The GNU++14 library function did a good job in initializing the allocated memory.

            Thanks for the helpful note.

»
3 года назад, # |
  Проголосовать: нравится -29 Проголосовать: не нравится

There us no difference between versions of the worst language in the world. Python us better and faster