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