25

Consider:

for (auto i = 0; i < g.size(); ++i)
    for (auto j = 0; j < g.size(); ++j) if (g[i][j] == 0) dfs(g, i, j), ++regions;
return regions;

I don't like one line code. What does the code execute in the if()?

I am confused by the "," sign.

Usually I would write it as:

  for (auto i = 0; i < g.size(); ++i)
  {
      for (auto j = 0; j < g.size(); ++j)
      {
          if (g[i][j] == 0)
          {
             dfs(g, i, j)
          }
          ,++regions; // I am not sure what to do here. Inside the "if" scope??
      }
} 
  return regions;
Gilad
  • 6,437
  • 14
  • 61
  • 119

1 Answers1

31

The programmer has used the comma operator to provide two unrelated expressions in a single statement. Because it's a single statement, both expressions are "inside" the if condition.

It's a poor hack, which would be better done with actual {} braces surrounding two statements.

Your example is not equivalent; it should be:

if (g[i][j] == 0) 
{
   dfs(g, i, j);
   ++regions;
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 8
    ohh god, why why why would anyone write this code. Thanks – Gilad May 11 '19 at 20:50
  • 8
    @Gilad Trying to be clever, most likely! And failing. – Lightness Races in Orbit May 11 '19 at 20:51
  • @Gilad a very smart programmer once said *Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.* What I took from this was write the stupidest possible code that can meet the requirements. Even if I can debug sneaky code, the person I hand it off to to maintain might not. – user4581301 May 11 '19 at 21:04
  • @user4581301 so there is another case where he uses it like so – Gilad May 11 '19 at 21:05
  • void dfs(vector>& g, int i, int j) { if (i >= 0 && j >= 0 && i < g.size() && j < g.size() && g[i][j] == 0) { g[i][j] = 1; dfs(g, i - 1, j), dfs(g, i + 1, j), dfs(g, i, j - 1), dfs(g, i, j + 1); } } – Gilad May 11 '19 at 21:05
  • I wonder if you can use this in loops too... Nope, you can't. – Constantinos Glynos May 11 '19 at 21:10
  • 4
    @LightnessRacesinOrbit This is a habit of old school programmers due to small monitor resolution (25 rows 80 columns) code was writing as short as possible. More code on one page better readability. Try read modern code on such monitor and you will see how many empty rows in it. – Andrey Sv May 11 '19 at 21:14
  • @Constantinos, you can use the comma operator in any expression, and you can use an expression statement as the body of a loop, so I’m curious what you mean can’t be used in loops. – prl May 11 '19 at 21:18
  • 3
    Of course, that hack is especially useful for macros, which one also should avoid assiduously. – Deduplicator May 11 '19 at 21:33
  • @prl: I tried a simple while loop with the comma operator that increments the counter to break out of the loop, but the clang refused to compile. Maybe I did it wrong... – Constantinos Glynos May 11 '19 at 21:52
  • 2
    @AndreySv Yep. Common in C. It eliminates the need to put braces in. Perfectly legible for anyone used to the comma operator idiom so long as the if and predicate are also indented. Less common practice these days so peeps aren't familiar with it. Code s/b written to be as clear as possible to as many programmers as possible. Within reason. – doug May 11 '19 at 22:05
  • @Deduplicator So true. Reducing use of macros was a principal driver for me switching to C++. – doug May 11 '19 at 22:07
  • In C I sometimes do `return log("bla"), E_FOO;` to save on vertical space, which means that when viewing the code, more of the function can be taken in at once. (I don't use that sort of error handing in C++) – M.M May 11 '19 at 22:45
  • 3
    @AndreySv Such programmers have had some thirty years to break that habit, i.e. since before C++ even existed. – Lightness Races in Orbit May 11 '19 at 22:59
  • 3
    @doug: Although the code is perfectly legible to me (hence the fast answer) I maintain that this is _not_ good code. So the two are not one and the same. – Lightness Races in Orbit May 11 '19 at 23:00
  • @Andrey Sv I suppose you are not a fan of a tab spacing of 8 then ([whether or not they are actual physical TAB characters](https://www.youtube.com/watch?v=MBWAP_8zxaM&t=8m49s))? – Peter Mortensen May 11 '19 at 23:04
  • @LightnessRacesinOrbit Its only [standard](http://eel.is/c++draft/expr.comma) no more no less. – Andrey Sv May 11 '19 at 23:51
  • @AndreySv Who claimed it's non-standard? – Lightness Races in Orbit May 12 '19 at 00:37
  • @LightnessRacesinOrbit Well, what is "good" code. When I come across a series of expressions separated by a comma it's immediately obvious they are only being used for side effects, unless the result of a comma expression is actually used which I find to not be intuitive. To me good code is something where the structure, naming, etc. conveys useful information about the program. I don't use the comma operator to chain side effect expressions these days but mostly because too few are familiar with it and may be confused. – doug May 12 '19 at 03:03
  • 1
    @LightnessRacesinOrbit Agreed. The mark of true cleverness is that the result looks simple, elegant, and obvious. Anything that looks "clever" actually isn't. – jpmc26 May 12 '19 at 03:27