Apparently $$$24$$$ hours without sleep and months of coding in scripting languages had the effect on me... During the contest I submitted this 310073998
Quick challenge: pause reading and find the bug in my solution

When I found out that I failed a div3D on not properly using int64_t I was quite surprised, because I double checked that I did it right. I felt very stupid at first, but then I got surprised even more when I figured how exactly this happened. Take a look at the line $$$25$$$
const& r = cr[i];
It appears that GCC allows to declare variable references omitting type declaration completely when cv-qualifier is present. Yes, without invoking type deduction using auto. To be precise expression in form
<cv-qualifier> &<variable-name> = <value>;
appears to be well-formed and compilable.
But what type you will end up using? You might expect GCC to be smart enough to put auto for you, but you are wrong. In this special case type will always default to int. In many cases this will immediately make code ill-formed due to <value> not being convertable to int. But in my case int64_t is actually implicitly convertable to int. Which is exactly what happened in my code: r gets int type and r*r gets truncated to $$$32$$$ bits.
Funny enough, not even #define int long long will save you in that case
Isn't that amazing?
Yes, -Wconversion compiler option will correctly produce the warning on creating defaulted-to-int reference to int64_t variable.
But why the hell this is even compilable in the first place!?
It appears that this default-to-int behaviour is a part of K&R C standard of C-language aging back to year $$$1978$$$. Almost the same age as my parents are.
Trying to reproduce and explore this issue I ended up with this code
#include <cstdio>
int main() {
long long int v1 = 1'000'000'000'001;
const &r1 = v1;
volatile int v2 = 42;
volatile &r2 = v2;
volatile int v3 = 42;
const volatile &r3 = v3;
printf("GCC %d.%d.%d\n", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
printf("r1 = %d\n", r1);
printf("r2 = %d\n", r2);
printf("r3 = %d\n", r3);
}
It appears to be compilable on all $$$3$$$ available G++ compilers on CF and on my local GCC 11.2.0 producing expected result of
GCC 11.2.0
r1 = -727379967
r2 = 42
r3 = 42
Exploring it in GodBolt I learned that this is a part of -fpermissive behaviour of GCC. But still, all versions of GCC that I checked in GodBolt will produce compile errors without -fpermissive option and produce warnings with -fpermissive. Other compilers also produce compile errors.
But I did not enable -fpermissive locally, neither did CodeForces (as long as Codeforces Command Lines (2023-10-06) are up to date). So, there are two questions to this:
- How do I configure GCC locally to produce compile errors on such code?
- How do I make CodeForces give compile errors to such code?









Is this a windows thing? locally I am seeing the error with codeforces compile options:
g++-14 -std=c++23 -Wall -Wextra -Wconversion -static -DONLINE_JUDGE -Wl,--stack=268435456 -O2 submit.cpp -o bin/submitTurns out it is actually a Windows issue, more precisely a MinGW issue. Thank you, TianyiChen, for pointing in that direction. I did not expect default behaviour of GCC to be platform-dependent.
Among many other extensions GCC has
ms-extensions, that aim to make language closer to MSVC dialect allowing a set of non-standard C/C++ features from it.StackOverflow: What does the -fms-extensions flag do exactly with GCC?
For some reason
ms-extensionsare enabled in MinGW by default.The problem is that
ms-extensionswere not properly updated for like $$$20$$$ years while GCC, MSVC and C++ were making a large progress. Soms-extensionsstill assume thatimplicit-intshould be allowed for MSVC compatibility, while neither of aformentioned $$$3$$$ independently assume it.Big thank you for Andrew Pinski, who clarified this https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119400
Answering the questions from the blog:
(1)
ms-extensionsare controlled with antagonistic compilation flags-fms-extensions/-fno-ms-extensions. Using the second one prevents this undesired behaviour. The victory!(2) I believe that, unlike optimization flags with
pragma GCC,-fno-ms-extensionsunfortunately cannot be set from inside source code.Here a proposition to add
-fno-ms-extensionsto CodeForces GCC compile options can be made, but I'm not sure. On the one hand, why someone who might have nothing to do with Windows and MSVC at all must have their code compiled with questionable extensions, that are here just by default and not by someone's conscious decision? On the other hand, this is very radical solution to seemingly non-problem: I'm likely the only one who got affected by this in any noticeable way on CF ever. And still it happened just because I was careless and made the mistake by myself in the first place.MikeMirzayanov Vladosiya may be you will have more concrete opinion in this
I would just write the
i64. Its 3 characters and makes the code easier to both read and debug