Is that an obfuscated retry?
-
Never has Kevin been a real C# programmer. His way to coding is so...
And reading his code is terribly hard. What's the meaning of the "or" operator in following line:result = PutPanoramaData(client, panoramaInfo, _storedPanoramaData.Thermo) || PutPanoramaData(client, panoramaInfo, _storedPanoramaData.Thermo);
Yes, he calls two times the same function with the same parameters. And a couple of lines below that snippet, he repeats that pattern with a different set of parameters. The boolean return value of the function seems to indicate a success flag. So he might have invented a simple way for a Retry functionality.
What a genius! I ought to be glad to have him on the team.
-
@BernieTheBernie
You should introduce Kevin to the while loopbool result = false while (!result) { PutPanoramaData(client, panoramaInfo, _storedPanoramaData.Thermo) }
Just think, much cleaner because you don't duplicate the parameter passes and have a possible sloppy pasta error!
-
@BernieTheBernie said in Is that an obfuscated retry?:
Yes, he calls two times the same function with the same parameters.
If at first you don't succeed...
-
...Skydiving is not for you.
-
@izzion I like how that post has a bug in it so it will never stop trying.
Edit: As for the OP, that's actually quite an ingenious way to do a retry. Pretty opaque though.
-
@bobjanova
The post was written in an Agile fashion.
-
@bobjanova said in Is that an obfuscated retry?:
@izzion I like how that post has a bug in it so it will never stop trying.
Edit: As for the OP, that's actually quite an ingenious way to do a retry. Pretty opaque though.
You can not prove that the call will not throw an exception
-
@TheCPUWizard
on success throw continue
-
@TheCPUWizard said in Is that an obfuscated retry?:
You can not prove that the call will not throw an exception
@bobjanova said in Is that an obfuscated retry?:
@izzion I like how that post has a bug in it so it will never stop trying.
Obviously he should have done:
function foo( ...args ) { try { // do stuff } catch { return foo( ...args ); } }
That way, if it fails too many times, you get an uncatchable
StackOverflowException
, that breaks the loop.
Filed under: Tail call recursion is a to
-
@error said in Is that an obfuscated retry?:
That way, if it fails too many times, you get an uncatchable
StackOverflowException
, that breaks the loop.Filed under: Tail call recursion is a to
-
My favorite tail recursion joke
-
@error_bot xkcd tail recursion
-
xkcd said in https://xkcd.com/1270/ :
Functional
(via https://www.explainxkcd.com/wiki/index.php?search=tail+recursion&title=Special%3ASearch&fulltext=1)
-
@Zecc It needs to be the permalink to that post; that one ends up linking to wherever thinks I am in the document (which doesn't really align with reality).
-
@izzion said in Is that an obfuscated retry?:
sloppy pasta error
My son had one of those last night. He dropped his plate of lasagna.
-
@BernieTheBernie said in Is that an obfuscated retry?:
So he might have invented a simple way for a Retry functionality.
Not really, I think that will execute both side of the or regardless...
-
@Tsaukpaetra said in Is that an obfuscated retry?:
@BernieTheBernie said in Is that an obfuscated retry?:
So he might have invented a simple way for a Retry functionality.
Not really, I think that will execute both side of the or regardless...
In C#, it wont. Some languages possibly will.
Short circuit evaluation is fairly common in languages. I've actually had to fix a bug because a developer of some "clever" code didn't know about it and depended on side effects that didn't happen because the method was never called.
-
@Tsaukpaetra said in Is that an obfuscated retry?: "Not really, I think that will execute both side of the or regardless... "
Not in any C family language, including JavaScript. Short circuit evaluation of things called || or && is so expected nowadays that a language that didn't do it would be a WTF in itself.
-
@bobjanova said in Is that an obfuscated retry?:
Not in any C family language
C++ allows overloading ope...
a language that didn't do it would be a WTF in itself.
...oh, I see you've covered that already.
-
@Gąska Yeah, that's why C# doesn't let you overload those. An overload which changes the fundamental semantics of a piece of language (as opposed to just making it return a different thing) is definitely a WTF.
-
@bobjanova said in Is that an obfuscated retry?:
@Gąska Yeah, that's why C# doesn't let you overload those. An overload which changes the fundamental semantics of a piece of language (as opposed to just making it return a different thing) is definitely a WTF.
Honestly, I kinda like that C++ lets you completely and utterly fuck yourself over if you so wish.
You don't have to.
I also like that you can create new objects and set them to this in destructors, great for what-the-fuck-is-going-on?!
-
@Carnage said in Is that an obfuscated retry?:
@bobjanova said in Is that an obfuscated retry?:
@Gąska Yeah, that's why C# doesn't let you overload those. An overload which changes the fundamental semantics of a piece of language (as opposed to just making it return a different thing) is definitely a WTF.
Honestly, I kinda like that C++ lets you completely and utterly fuck yourself over if you so wish.
I'd just prefer if it didn't completely and utterly fuck you over even if you do nothing out of ordinary.
I also like that you can create new objects and set them to this in destructors, great for what-the-fuck-is-going-on?!
You mean like this?
class Foo { ~Foo() { *this = Foo{}; } }
I don't quite see its destructive potential, other than people spending way too much time analyzing this no-op.
delete this;
is much better (and the last time I checked, well-formed under certain circumstances).
-
@Carnage said in Is that an obfuscated retry?:
You don't have to.
See also: why do people climb mountains.
-
@Applied-Mediocrity said in Is that an obfuscated retry?:
@Carnage said in Is that an obfuscated retry?:
You don't have to.
See also: why do people climb mountains.
There, there.
-
@Gąska said in Is that an obfuscated retry?:
@bobjanova said in Is that an obfuscated retry?:
Not in any C family language
C++ allows overloading ope...
a language that didn't do it would be a WTF in itself.
...oh, I see you've covered that already.
And that's exactly why overloading
||
and&&
is considered a terrible idea. (I have no idea why it's not deprecated, but I'm sure some piece of garbage is using it like Microsoft's use ofLooked it up and I guess it's possible to make something with expression templates that has the desired semantics)operator&
for their old, terrible COM bindings.
-
@Gąska said in Is that an obfuscated retry?:
@Carnage said in Is that an obfuscated retry?:
@bobjanova said in Is that an obfuscated retry?:
@Gąska Yeah, that's why C# doesn't let you overload those. An overload which changes the fundamental semantics of a piece of language (as opposed to just making it return a different thing) is definitely a WTF.
Honestly, I kinda like that C++ lets you completely and utterly fuck yourself over if you so wish.
I'd just prefer if it didn't completely and utterly fuck you over even if you do nothing out of ordinary.
I also like that you can create new objects and set them to this in destructors, great for what-the-fuck-is-going-on?!
You mean like this?
class Foo { ~Foo() { *this = Foo{}; } }
I don't quite see its destructive potential, other than people spending way too much time analyzing this no-op.
delete this;
is much better (and the last time I checked, well-formed under certain circumstances).No, you can change the type as well.
The destructive potential isn't that great, but it will definitely throw you a curve ball if someone does that in code you have to work with.
-
@Carnage said in Is that an obfuscated retry?:
The destructive potential isn't that great
Oh ye of little faith...
-
@HardwareGeek said in Is that an obfuscated retry?:
@Carnage said in Is that an obfuscated retry?:
The destructive potential isn't that great
Oh ye of little faith...
Plenty of things can be abused far more in C++. The main thing with this bit is that it's quite esoteric so most people would not have any idea what they are looking at.
-
@Carnage said in Is that an obfuscated retry?:
Honestly, I kinda like that C++ lets you completely and utterly fuck yourself over if you so wish.
When C++ decides that it's going to use a different overloaded method to the one you expected and so totally break the code (despite it ostensibly still “working” in that it continues to compile), that's not so fun. The coercions to boolean can cause all sorts of merry mayhem.
Still not as bad as actually trying to replace the memory management code in STL classes. You're supposed to be able to do it, but you're in for a world of weird pain when you try. Assuming you want things to work with more than one compiler…
-
@dkf said in Is that an obfuscated retry?:
Still not as bad as actually trying to replace the memory management code in STL classes.
And even when you'd never even dream of doing that, stack traces are cluttered with
<std::allocator>
everywhere. It's not as if they aren't hard enough to read without that.
-
@TheCPUWizard said in Is that an obfuscated retry?:
You can not prove that the call will not throw an exception
See my other post at https://what.thedailywtf.com/topic/27164/lasterror ...
-
@BernieTheBernie said in Is that an obfuscated retry?:
@TheCPUWizard said in Is that an obfuscated retry?:
You can not prove that the call will not throw an exception
See my other post at https://what.thedailywtf.com/topic/27164/lasterror ...
The easiest way to prove that no exceptions are thrown is to not link in the code that actually does the throwing of the exception. Yes, you can prevent that from being linked in C++; do it right and it effectively forces everything to be
noexcept
. This is commonly done with embedded code, where “zero cost” exceptions are very much regarded as not being zero cost. There's a lot of extra code and metadata required to handle exceptions, and embedded platforms don't have a lot of spare space for code. That basically means No STL For You as a lot of its critical semantics (especially in relation to memory management) depend on exception throwing for the edge cases; you end up having to homebrew all your class library and by that point you might as well be using C.Worse, the compiler can't optimise out the throwing of exceptions in C++. Because why would anyone want to do that?! It's not like you could ever conceive of replacing exceptions with jump threading in heavily inlined code… O WAIT!
-
@dkf said in Is that an obfuscated retry?:
you end up having to homebrew all your class library and by that point you might as well be using C.
Your homebrewed library can use much nicer abstractions if you don't stick to C.
-
@topspin said in Is that an obfuscated retry?:
Your homebrewed library can use much nicer abstractions if you don't stick to C.
Except abstractions are rarely zero cost, and we're pushing things fairly close to the limit as it stands. We're more likely to go lower level, down to assembler, than up to something like C++ or Rust. Runtimes like those for Java and C# are right out. (Our largest current binaries used to have about 300 bytes free after loading, but have a bit more now that we've managed to find a way to compress logging statements.)
-
@dkf said in Is that an obfuscated retry?:
Still not as bad as actually trying to replace the memory management code in STL classes. You're supposed to be able to do it, but you're in for a world of weird pain when you try. Assuming you want things to work with more than one compiler…
Hm? I've never written one myself, but I've read code that defined its own allocators, and they seemed reasonably straightforward. Maybe I'm missing some details because I didn't have to write and debug them?
-
@dfdub said in Is that an obfuscated retry?:
I've never written one myself, but I've read code that defined its own allocators, and they seemed reasonably straightforward. Maybe I'm missing some details because I didn't have to write and debug them?
The problem was that when you do that, you have to define some extra methods to make it all work. It's not just a simple matter of plugging in a basic allocator/deallocator function pair. Or it is with some compilers and not others. (As I recall, the allocator/deallocator need some extra gluing internally as well.) The code concerned was a very fast lock-free inter-thread message queue; it needed a very fast custom memory manager to avoid most of the critical locks (replacing deallocation with a second queue to return memory to the producer thread).
I don't really remember the exact details, as I got rid of the branch concerned a few years ago when it became clear that the bottleneck was elsewhere (and solutions that didn't need a working C++ compiler on all our users' computers were superior for deployment). It solved a problem we didn't really actually have, and introduced too many of its own troubles.
-
@dkf said in Is that an obfuscated retry?:
The problem was that when you do that, you have to define some extra methods to make it all work. It's not just a simple matter of plugging in a basic allocator/deallocator function pair.
The necessary boilerplate for allocators has become a bit better with C++11: https://howardhinnant.github.io/allocator_boilerplate.html
You probably want a custom placement new, placement new[] and matching delete and delete[] as well.I'm not saying it's intuitive, just that implementing an allocator is definitely a solvable problem for the average developer and not considerably more complex than the rest of the STL.
-
@dkf said in Is that an obfuscated retry?:
The code concerned was a very fast lock-free inter-thread message queue; it needed a very fast custom memory manager to avoid most of the critical locks (replacing deallocation with a second queue to return memory to the producer thread).
Sounds familiar. I've got one of those as well, in plain C, and the memory allocation (custom, passing back through a global pool 1k chunks at a time) is definitely one of the slow bits.
-
@Carnage said in Is that an obfuscated retry?:
Short circuit evaluation is fairly common in languages. I've actually had to fix a bug because a developer of some "clever" code didn't know about it and depended on side effects that didn't happen because the method was never called.
c# to the rescue, | applied to stuff other than "integral numeric types or the char type" is the "logical or" that always executes both sides, whilst || does short circuit
from wtf docs
Binary & (logical AND), | (logical OR), and ^ (logical exclusive OR) operators. Those operators always evaluate both operands.
For operands of the integral numeric types, the &, |, and ^ operators perform bitwise logical operations.
-
@OloEopia said in Is that an obfuscated retry?:
@Carnage said in Is that an obfuscated retry?:
Short circuit evaluation is fairly common in languages. I've actually had to fix a bug because a developer of some "clever" code didn't know about it and depended on side effects that didn't happen because the method was never called.
c# to the rescue, | applied to stuff other than "integral numeric types or the char type" is the "logical or" that always executes both sides, whilst || does short circuit
from wtf docs
Binary & (logical AND), | (logical OR), and ^ (logical exclusive OR) operators. Those operators always evaluate both operands.
For operands of the integral numeric types, the &, |, and ^ operators perform bitwise logical operations.
-
@OloEopia said in Is that an obfuscated retry?:
@Carnage said in Is that an obfuscated retry?:
Short circuit evaluation is fairly common in languages. I've actually had to fix a bug because a developer of some "clever" code didn't know about it and depended on side effects that didn't happen because the method was never called.
c# to the rescue, | applied to stuff other than "integral numeric types or the char type" is the "logical or" that always executes both sides, whilst || does short circuit
from wtf docs
Binary & (logical AND), | (logical OR), and ^ (logical exclusive OR) operators. Those operators always evaluate both operands.
For operands of the integral numeric types, the &, |, and ^ operators perform bitwise logical operations.Needless to say this is dangerous, because two truthy values bitwise anded together can give a falsey result.
-
@dfdub said in Is that an obfuscated retry?:
The necessary boilerplate for allocators has become a bit better with C++11
I didn't mention, but this was already with C++11 (no legacy, no need to restrict to earlier language versions). You're probably better off waiting for C++17 for actual portability. (I think
clang
gets the C++11 support right butgcc
doesn't unless you add a bunch of stupid extra boilerplate.)
-
@PleegWat said in Is that an obfuscated retry?:
I've got one of those as well, in plain C, and the memory allocation (custom, passing back through a global pool 1k chunks at a time) is definitely one of the slow bits.
Cleverness with pooling allocators is one of the main ways of accelerating a program, and is very important for C and C++. You don't need it for Java as the VM's GC system actually works by using mostly thread-bound pools; in our testing with real-world loads we were finding that Java was out-performing C++ on this task on average because of the memory management effects. C++ did have much lower jitter in its performance, but was just overall slower about 98% of the time (at least before I implemented the faster allocator; we hadn't got around to full performance testing when we decided to give up on the approach).
Heck, for just one of these datastreams I was dealing with, Python is quite fast enough to service it without performance loss. It's only for dealing with parallelism that you want something else, and most compiled languages can saturate a gigabit link no problem.
-
@PleegWat said in Is that an obfuscated retry?:
Needless to say this is dangerous, because two truthy values bitwise anded together can give a falsey result.
The whole purpose of the
&
operator is for doing bit masking. That is its job.
-
@PleegWat said in Is that an obfuscated retry?:
@OloEopia said in Is that an obfuscated retry?:
@Carnage said in Is that an obfuscated retry?:
Short circuit evaluation is fairly common in languages. I've actually had to fix a bug because a developer of some "clever" code didn't know about it and depended on side effects that didn't happen because the method was never called.
c# to the rescue, | applied to stuff other than "integral numeric types or the char type" is the "logical or" that always executes both sides, whilst || does short circuit
from wtf docs
Binary & (logical AND), | (logical OR), and ^ (logical exclusive OR) operators. Those operators always evaluate both operands.
For operands of the integral numeric types, the &, |, and ^ operators perform bitwise logical operations.Needless to say this is dangerous, because two truthy values bitwise anded together can give a falsey result.
In C#? Example please.
-
-
@Zecc I thought you're talking about stuff other than "integral numeric types or the char type", because that's what the post you were replying to was talking about.
-
@PleegWat said in Is that an obfuscated retry?:
@OloEopia said in Is that an obfuscated retry?:
@Carnage said in Is that an obfuscated retry?:
Short circuit evaluation is fairly common in languages. I've actually had to fix a bug because a developer of some "clever" code didn't know about it and depended on side effects that didn't happen because the method was never called.
c# to the rescue, | applied to stuff other than "integral numeric types or the char type" is the "logical or" that always executes both sides, whilst || does short circuit
from wtf docs
Binary & (logical AND), | (logical OR), and ^ (logical exclusive OR) operators. Those operators always evaluate both operands.
For operands of the integral numeric types, the &, |, and ^ operators perform bitwise logical operations.Needless to say this is dangerous, because two truthy values bitwise anded together can give a falsey result.
In C# there is no "truthy", there's only bool.
-
@Gąska I'm going to hell.
using System; class MainClass { public static void Main (string[] args) { Wtf a = new Wtf(1); Wtf b = new Wtf(4); Console.WriteLine( "a: {0}", Convert.ToBoolean(a) ); Console.WriteLine( "b: {0}", Convert.ToBoolean(b) ); Console.WriteLine( "a & b: {0}", Convert.ToBoolean(a & b) ); } } class Wtf { int inner; public Wtf(int i) { inner = i; } public static bool operator true(Wtf v) => true; public static bool operator false(Wtf v) => true; public static bool operator & (Wtf v1, Wtf v2) => false; public static implicit operator int (Wtf v) => v.inner; }
-
@Zecc said in Is that an obfuscated retry?:
I'm going to hell.