Asked  6 Months ago    Answers:  5   Viewed   40 times

One of the tips for jslint tool is:

++ and --
The ++ (increment) and -- (decrement) operators have been known to contribute to bad code by encouraging excessive trickiness. They are second only to faulty architecture in enabling to viruses and other security menaces. There is a plusplus option that prohibits the use of these operators.

I know that PHP constructs like $foo[$bar++] has may easily result with off-by-one errors, but I couldn't figure out a better way to control the loop than a while( a < 10 ) do { /* foo */ a++; } or for (var i=0; i<10; i++) { /* foo */ }.

Is the jslint highlighting them because there are some similar languages that lack the "++" and "--" syntax or handle it differently, or are there other rationales for avoiding "++" and "--" that I might be missing?

 Answers

18

My view is to always use ++ and -- by themselves on a single line, as in:

i++;
array[i] = foo;

instead of

array[++i] = foo;

Anything beyond that can be confusing to some programmers and is just not worth it in my view. For loops are an exception, as the use of the increment operator is idiomatic and thus always clear.

Tuesday, June 1, 2021
 
tompave
answered 6 Months ago
87

++ is not an operator. It is two + operators. The + operator is the identity operator, which does nothing. (Clarification: the + and - unary operators only work on numbers, but I presume that you wouldn't expect a hypothetical ++ operator to work on strings.)

++count

Parses as

+(+count)

Which translates to

count

You have to use the slightly longer += operator to do what you want to do:

count += 1

I suspect the ++ and -- operators were left out for consistency and simplicity. I don't know the exact argument Guido van Rossum gave for the decision, but I can imagine a few arguments:

  • Simpler parsing. Technically, parsing ++count is ambiguous, as it could be +, +, count (two unary + operators) just as easily as it could be ++, count (one unary ++ operator). It's not a significant syntactic ambiguity, but it does exist.
  • Simpler language. ++ is nothing more than a synonym for += 1. It was a shorthand invented because C compilers were stupid and didn't know how to optimize a += 1 into the inc instruction most computers have. In this day of optimizing compilers and bytecode interpreted languages, adding operators to a language to allow programmers to optimize their code is usually frowned upon, especially in a language like Python that is designed to be consistent and readable.
  • Confusing side-effects. One common newbie error in languages with ++ operators is mixing up the differences (both in precedence and in return value) between the pre- and post-increment/decrement operators, and Python likes to eliminate language "gotcha"-s. The precedence issues of pre-/post-increment in C are pretty hairy, and incredibly easy to mess up.
Tuesday, June 1, 2021
 
Giovanni
answered 6 Months ago
68

Haskell's grammar doesn't allow you to use - like that. Use the subtract function instead:

(subtract 3) 2
Saturday, June 19, 2021
 
Hilmi
answered 6 Months ago
84
 x = 5;  y = 10;
    System.out.println(z = y *= x++); // output is 50 -->z=y=y*x i.e, z=y=10*5 (now, after evaluation of the expression, x is incremented to 6)
    x = 2; y = 3; z = 4;
    System.out.println("Result = "+ z + y++ * x); // output is Result = 46 --> from Right to left . y++ * x happens first..So, 3 * 2 = 6 (now, y will be incremented to 4) then "Result = " +z (String) + number (y++ * z) will be concatenated as Strings.
    x = 5;
    System.out.println( x++*x); // output is 30 --> 5 * (5+1 i.e, x is already incremented to 6 when you do x++ so its like 5 *6 )
    x = 5;
    System.out.println( x*x++); // output is 25 -- > 5 * 5 (x will be incremented now)
Wednesday, September 1, 2021
 
VieStar
answered 3 Months ago
93

Before I start, let me point out that one should generally avoid situations where one you both sets and reads a variable within an expression.


First, let's look at operand evaluation order. This isn't defined for many operators, but it is defined for the list operator. It's documented to evaluate its operands in left-to-right order[1]. That means that printf's arguments are evaluated in the following order:

  1. "%d %d %d %d"
  2. $a
  3. ++$a
  4. $a++
  5. $a

The key lies in knowing that $a doesn't place a copy of the value of $a on the stack. It places the scalar itself (a SV*, in C terms). In Perl jargon, we say the stack element is aliased to $a[2]. In computing theory, you'd say the arguments are passed by reference.

And the same goes for ++$a, but $a++ necessarily places a copy of $a on the stack.

This means we can view the above printf call as equivalent to

use Data::Alias qw( alias );

{
    local @_;
    alias $_[0] = "%d %d %d %d";
    alias $_[1] = $a;    # Places $a on the stack.
    alias $_[2] = ++$a;  # Adds one to $a and places $a on the stack.
    alias $_[3] = $a++;  # Places a copy of $a on the stack and adds one to $a.
    alias $_[4] = $a;    # Places $a on the stack.
    &CORE::printf;
 }

By the time $a++ is called, $a contains 6.

By the time printf is called, $a contains 7.


The workaround is to make copies of the values.

$ perl -le'$a = 5; my @b = ($a, ++$a, $a++, $a); print "@b";'
7 7 6 7

$ perl -le'$a = 5; my @b = (0+$a, 0+(++$a), $a++, $a); print "@b";'
5 6 6 7

  1. From perlop, "In list context, it's just the list argument separator, and inserts both its arguments into the list. These arguments are also evaluated from left to right."

  2. From perlsyn, "Any arguments passed in show up in the array @_. Therefore, if you called a function with two arguments, those would be stored in $_[0] and $_[1]. The array @_ is a local array, but its elements are aliases for the actual scalar parameters."

Thursday, November 4, 2021
 
Micah Alcorn
answered 4 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share