C++'s rules can be pesky some times
a.cpp:
#include "Shape.h" // includes class Shape, with virtual functions on it
int callback(int value, Shape* s)
{
// aggregates areas
return value + s->getArea();
}
// Some boring work... we don't even call this function
int aggrigateAreas(Shape* begin, Shape* end)
{
int rval = 0;
for (Shape* iter = begin; iter != end; iter++)
rval = callback(rval, iter);
return rval;
}
b.cpp:
#include "Shape.h"
int callback(Shape* s)
{
// aggrigate perimieters
return s->getPerimiter();
}
// doSomethingImportant will actually do something for us
int doSomethingImportant(Shape* s)
{
return callback(s); // this was more complicated in real life
}
main.cpp
#include "Shape.h"
#include <iostream>
int doSomethingImportant(Shape* s);
int main() {
Square s(1); // square with side length 1
std::cout << doSomethingImportant(&s); // should print 4, right?
return 0;
}
Sadly, C/C++ is rather unfriendly if you have two functions in different translation units with different names. They call it a ODR violation (One Definition Rule) and it's Undefined Behavior. As it so happens, if the linker is not being kind to you today, your call to callback
in doSomethingImportant
can end up calling the callback
in a.cpp. This is bad enough, but they also don't have the same signatures. s
may get some garbage value, such as something which causes the virtual function lookup of getArea
() to return the address just before main
, creating an infinite loop when called. It even gets a few broken opcodes just right to maladjust the stack back to its initials stack height, so you don't even get a sane stack overflow.
Is this against the rules of code golf? Maybe. I am trying to claim a win by getting very unlucky with a compiler's handling of undefined behavior. Technically that's outside of the spec of the language.
However, the scars I put into my cubicle walls that day, dug deep with my fingers as I screamed in agony remain. Dug over the course of that whole 12 hour work day, with the debugger taunting me as I went (You're {bleep}ing kidding me! Why did the debugger put me back in a.cpp again! I commented out all calls to that file wholesale! Maybe I should recompile the world again)... that has to qualify as "underhanded" somehow, right? Please?
I will not forget to open the anonymous namespace to store my callbacks
I will not forget to open the anonymous namespace to store my callbacks
I will not forget to open the anonymous namespace to store my callbacks
1
I'm voting to close this question as off-topic because underhanded challenges are no-longer on-topic here. http://meta.codegolf.stackexchange.com/a/8326/20469
– cat – 2016-04-15T14:20:02.7176Could someone please explain what I can do to make the question less broad? I am new here. Thank you! – Number9 – 2014-03-16T13:58:53.563
6This is just going to be a big list of typos and beginner's mistakes which cause loops. – Bill Woodger – 2014-03-17T00:51:25.707
Interesting question, but I haven't seen any truly creative answers yet. I promise up votes to anyone who doesn't use loops or obvious recursion! – ApproachingDarknessFish – 2014-03-17T05:35:03.107
@ValekHalfHeart Does my answer qualify? ;) There is a loop... but I wouldn't call the bug obvious. – Legat – 2014-03-17T14:31:30.730
@ValekHalfHeart No loops, no recursions: http://codegolf.stackexchange.com/a/24391/14901.
– VisioN – 2014-03-17T16:27:23.993http://codegolf.stackexchange.com/questions/24304/why-isnt-it-ending/24645#24645 – evil999man – 2014-03-21T03:44:54.010
14I don't know if this counts, but my Microsoft Office is behaving exactly like this at the moment. – Level River St – 2014-03-22T11:40:53.417
You have just described every
FORTRAN
program I have look at. – ja72 – 2014-03-26T20:21:02.393Did anybody see the PostScript answer? It does not use floating-point precision, but self-mutilating code. – luser droog – 2014-04-28T05:02:36.563
I feel like I've done this so many times by accident in Awk and now I can't think of a way to make it happen on purpose. – shadowtalker – 2014-08-09T12:22:31.103