# Some people just want to watch the world burn

This topic is 782 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

What a difference one little ascii 32 makes.

##### Share on other sites

For once SO technical discussions deviates slightly from strictly Q&A, lightens up and are a bit more interesting, less formal and more like gamedev, some even playing the demon's advocate! Loosen up a bit mates  :D

Yeah, that compiles ,  and so does ...

  int a = 10;
while ( a ++<+ 0 ){...}
while ( a -->+ 0 ){...}
while ( a ++>+ 0 ){...}
while ( a --<+ 0 ){...}
while ( a -->- 0 ){...}
while ( a ++>- 0 ){...}
while ( a --<- 0 ){...}
while ( a ++<- 0 ){...} 

you can make a sense of this

while (  a -->  0 ){ .. }      as    while ( (a --) > 0 ){ .. }

but how do you make a sense of  this

while (  a --> +  0 ){ .. }   as    while ( (a --) > + 0 ){ .. }

But I agree this one is really crazy :lol: ,  EDIT:  doesn't compile (in Java) as SOTL points out, it compiles in C++
while ( a --\
\
\
\
> 0 ){}
Edited by greyhounder

##### Share on other sites

I use that "operator" as an easy tool to prevent off-by-one errors.

I'm open to hearing about why it's insidious, but have yet to hear a good reason. In debates with others, the only argument they offered up was "It's confusing to beginners" - but so is every other aspect of C++. If it confuses them, they can google or ask questions, and then it can forever cease to confuse them. It doesn't inherently lead to more complex or confusing code, like some C++ features do when abused.

Essentially, either someone understands it, or doesn't understand it.
If they understand it, there's no problem, and they move on.
If they don't understand it, clearly they would ask someone about it, google about it (and find instant explanations), and then henceforth they are a part of Group A and move on.

This "operator" isn't capable of being "abused", because anywhere you are using it is somewhere where you are already going to iterate backwards. It's not a code-flow issue. And, like I mentioned, it really is beneficial for reducing off-by-one errors - one of the most common source of bugs and security flaws in programming history, irrespective of language.

Here's a few functions from my code:
[rollup=Code from my codebase]
(this is a lower level function, that safer functions are built ontop of - which explains the use of raw strings and the same-size assumption)

inline bool StringCompare(const char *strA, const char *strB, unsigned size)
{
//We go backwards, because it seems to me that strings are more likely to be similar
//at the beginning of the string, and vary towards the end of it.
//(For example, in a filepath, the first half or more might be identical)
for(unsigned i = size; i--> 0;)
{
if(strA[i] != strB[i])
return false;
}

return true;
}

//Compares two strings for equivalence, making the assumption that they are both the same length.
//'size' is the length of both strings. The comparison is case-insensitive.
//Returns true if they are both equal, and false otherwise.
inline bool StringCompare_CaseIn(const char *strA, const char *strB, unsigned size)
{
//We go backwards, because it seems to me that strings are more likely to be similar
//at the beginning of the string, and vary towards the end of it.
//(For example, in a filepath, the first half or more might be identical)
for(unsigned i = size; i--> 0;)
{
if(ToLower_Fast(strA[i]) != ToLower_Fast(strB[i]))
return false;
}

return true;
}

Or here:

//Finds the last character in 'str', matching 'charValidatorFunc', starting backwords from 'pos' (if std::string::npos, then starting at the end of 'str').
//Returns std::string::npos if no character is found.
size_t FindLast(const std::string &str, CharValidatorFunc charValidatorFunc, size_t pos)
{
if(pos == std::string::npos || pos > str.size())
pos = str.size();

for(; pos--> 0;)
{
if(charValidatorFunc(str[pos]))
return pos;
}

return std::string::npos;
}


Or here: (error reporting of cyclic linking in config file DSL)

//Make sure we haven't already visited this file (we don't want infinite loops).
if(Contains(visitedFiles, filename))
{
Log::Message message(MSG_SOURCE("ParseFile", Log::Severity::Error));
message << "Recursive infinite loop detected, when trying to include " << Log_HighlightBad(GetFilenameFromPath(filename)) << ".\n"
<< Log::IndentUp << "#include " << Log_DisplayPath(filename) << "\n"
<< Log::IndentDown << "From: \n" << Log::IndentUp;

for(size_t i = visitedFiles.size(); i--> 0; )
{
message << Log_DisplayPath(visitedFiles[i]) << "\n";
}

message << Log::FlushStream;

return false;
}


[/rollup]

But I agree this one is really crazy :lol: , and rightly doesn't compile

while ( a --\
\
\
\
> 0 ){}

That compiles fine. Note that in C++, a backslash at the end of a line (if the very last character) hides the newline, making the following line parse as a single line.

For example:

//                          v--- backslash
#define Meow(kitty, kibble) \
std::cout << "The backslash extends the macro onto a second line." << "Also, kitties." << std::endl;

##### Share on other sites

Oh... So i will edit the above post then, because i was in Java.

##### Share on other sites

I'm open to hearing about why it's insidious, but have yet to hear a good reason.

That the -> operator is actually a thing and I had to stop and think to figure out how it was supposed to be parsed (because I kept seeing - -> instead of -- >). You definitely don't want to slow down people like that, especially not during crunch period. (and yes, this is all a matter of where whitespace goes, the operation itself is fine)

Also I can attest to the string thing, I swear. I reduced loading times from 4-5 seconds to a fraction of a second just by computing a "quickhash" of each string (just add every character) when the list was first generated, then when it searched for a string it'd compare the quickhash first. Turns out that a lot of filenames differed only in their suffix (e.g. run_1, run_2, run_3, and so on - yeah, talking about animations here). A naïve comparison would have to scan practically the whole strings before failing, but the quickhash made them fail immediately. That the quickhash was stored alongside the pointer (and hence didn't need an extra dereference) probably also helped regarding the cache.

Obviously only useful for things like lists where you compute the quickhash of those strings only once then reuse it over and over, but it's definitely worth it even though it's quite simple to implement.

##### Share on other sites

I'm open to hearing about why it's insidious, but have yet to hear a good reason.

That the -> operator is actually a thing

That's reasonable. I've never parsed it that way, but I can understand someone getting confused by that at first glance, especially the way I didn't have a space between the --> and my iterator.

##### Share on other sites

x can go to zero even faster in opposite direction

int x = 10;

while( 0 <---- x )
{
printf("%d ", x);
}
8 6 4 2

You can control speed with an arrow!

int x = 100;

while( 0 <-------------------- x )
{
printf("%d ", x);
}
90 80 70 60 50 40 30 20 10

Sad thing is, this actually compiles.  :unsure:

1. 1
Rutin
26
2. 2
3. 3
JoeJ
20
4. 4
5. 5

• 10
• 10
• 9
• 9
• 10
• ### Forum Statistics

• Total Topics
631751
• Total Posts
3002087
×