I've bumped into this blog post by imtiyazrasool92 (unfortunately, it's already deleted due to downvotes). They've found out that simply declaring a global variable called read
makes your program behave strangely on Codeforces: the outcome of 130645392 is RUNTIME_ERROR
, Exit code is 2147483647
, and here is the code:
#include <iostream>
int read;
int main(){
std::ios_base::sync_with_stdio(false);
std::cin >> read;
}
I was unable to minimize the example any further.
The original post was even more interesting: 130642683 is Accepted, but 130643108 is Runtime Error all of a sudden.
The compiler on Codeforces is G++17 9.2.0 (64 bit, msys2)
. However, I was able to reproduce the issue both on my local machine (g++ (Rev2, Built by MSYS2 project) 10.3.0
) and the latest GCC on Godbolt as long as the -static
key is used for compilation just like on Codeforces. Clang is also affected.
It looks like the read
variable here replaces the standard Linux read
function (which is emulated by msys2). Here is a symmetrical example:
#include <iostream>
int write;
int main(){
std::ios_base::sync_with_stdio(false);
std::cout << 10;
}
And here is one more (130646314), although now I at least get some warnings:
int malloc;
int main(){
}
a.cpp:1:5: warning: built-in function 'malloc' declared as non-function [-Wbuiltin-declaration-mismatch]
1 | int malloc;
| ^~~~~~
My understanding is that all these examples invoke ODR violation, which makes the program ill-formed (invalid) without any requirements on the compiler to emit the error. However, I am not sure, so I asked on StackOverflow.
Any other ideas?
Auto comment: topic has been updated by yeputons (previous revision, new revision, compare).
First of all I want to say that my head hurts from the amount of disrespect you got on StackOverflow.
I may be wrong, but I think it has to do with how the linking process works and especially the
-static
flag. Without the flag, the c runtime (CRT) which contains definitions of symbols such asread
(a function) will be linked dynamically i.e. loaded when you run the executable. If you link the CRT statically, as with any library, the linker will only use definitions from the library for symbols declared, but not defined in the executable — such asread
. However, since you definedread
as a global variable of typeint
, it will be skipped in the linking step, so when you ultimately callread
fromcin>>...
, it will try to call it, but it's not a function, thus crashing.The fact that the accepted answer is by someone named "BetterThanYou" makes this so much funnier.
i found out that it gives RTE only if we use variable of read name and add
this line in code. without this line it works fine
Submission with this line : 130651006 Submission without this line : 130650894
I've been using a global function called
read()
in my template for years...I use a
read()
function as well (it's in my fastio template), but I believe that's actually fine, because the problem seems to exist withread(int fd, void *buf, size_t count)
(link), and C++ can differentiate between those two functions.However it cannot have a variable with the same name as a function and know which one to call, so that's probably why it fails (or maybe because it's a runtime error and functions are really just pointers, it might be trying to call a function thinking that
int read
is a pointer to something). Either way, a functionread()
won't cause problems.I mean the KGB won't come arrest you if you define a global variable named "read" so it must be legal.
with the kgb you never know