11

There is a common argument about multiple variable initialisation in a one liner, that is :

Consider for example int i, j = 1; which might lead some people to mistakingly believe both variables are being initialized

We could argue that someone should know enough the syntax of his language to not mistaken about that. Another argument could be as developers we learn so many languages we can make mistakes between the specificities between languages.

However for that very specific case I'm wondering the following does it even exists a language where the very syntax i, j=1 initialize both variable ?

If not that argument then doesn't apply.

13
  • 2
    If your language is sane, the potential confusion is harmless because accessing an uninitialized variable triggers a compiler error. Commented Mar 6, 2018 at 14:16
  • 4
    @CodesInChaos are you saying C isn't sane?
    – Baldrickk
    Commented Mar 6, 2018 at 14:37
  • 2
    Just because a language allows something doesn't mean you aren't causing the humans needless pain. The only place this code is called for is during quizzes designed to punish those who haven't memorized the language specification. I always failed these types of questions. Bleh. Commented Mar 6, 2018 at 15:23
  • 2
    In Visual Basic 6 Dim Apple, Orange, Pear as Fruit is a legal declaration. Suppose you do not know VB. Is your first impression that Apple is of type Fruit? It is not. Remember, languages are often read by people who are not experts in that language; if you are an expert, use the language wisely to communicate your intentions clearly even to non-experts. I never use multiple initializations in any language. Commented Mar 6, 2018 at 15:36
  • 13
    Similarly: consider var x = 1, y = 1.5; Is this the same as int x = 1; double y = 1.5; or is it the same as double x = 1, y = 1.5;? When we added var to C# 3.0 I did a poll and discovered that about half the people believed that the first was "obviously" correct and the other half believed the other one was "obviously" correct, and so we made it illegal. A feature that misleads fully half the population is a bad feature. Commented Mar 6, 2018 at 15:39

2 Answers 2

37

I think not, but that's not the point. The point is that i, j = 0 is very easily mistaken for i = j = 0, which does initialize both. Clarity is the most important requirement on source code next to correctness, and the fact that this question even arises proves that the clarity is suboptimal.

15
  • 3
    I also would argue that if such a statement does not initialize both statements, why does it even exist? Commented Mar 6, 2018 at 13:47
  • 2
    @BerinLoritsch depends on language. This is frequently done in JavaScript because of declaration hoisting: it is considered best practice by many to declare variables at the top of the scope in which they are available even if you don't initialize them until the spot they're used in the code. Almost all code transformation tools output in this fashion. Commented Mar 6, 2018 at 14:07
  • 1
    I suppose it's one thing if a code output tool did this, since that is supposed to be trusted. However, for humans I would recommend against it combining declaration and initialization of the last element only on one line. It just looks like a bug waiting to happen. Commented Mar 6, 2018 at 14:16
  • 2
    @JaredSmith Besides Maple, I can't think of a language where this is currently desired, even C now prefers closer to scope (like C++ and most other languages with half decent static compilers) because it gives the benefit of stopping potential bugs and allows the compiler to decide what to do with the variable as long as the functionality doesn't change, potentially allowing better optimizations given that you could get away with less registers.
    – Krupip
    Commented Mar 6, 2018 at 14:25
  • 6
    Regardless of the language, one should ask "What is the benefit of writing int i, j=1 versus int i; int j = 1 (or even better, separate lines)?"
    – chepner
    Commented Mar 6, 2018 at 14:43
2

I think, you can argue for either side:

  • Kontra i, j = 0:
    Mathematicians do use this to mean that both i and j are supposed to be zero.

  • Pro i, j = 0:
    It's a simple matter of knowing the precedence of your operators. And if you are doubtful about their precedence, now is the time to look it up.

    It's the same reason why we write stuff like a.b += c[i]*d[i]; without the parentheses. Of course this is equivalent to (a.b) += ((c[i])*(d[i]));, but programmers can be expected to know the precedence of the most used operators by heart, and be able to look up the precedence of operators when they are not sure. Thus, parentheses are generally considered useless clutter unless they force a different evaluation order than the operator precedence would prescribe.

    Of course, there are exceptions. The precedence of << and + is generally considered ambiguous enough to warant parentheses in either case. But that is the exception that proves the rule.

I, for one, would fall more onto the Pro side, but I'm prepared to stick to any styleguide that forbids such declarations. It's just not a matter worth fighting over.

6
  • 7
    I note that int i, j = 0; has no operators in it. The only expression in that statement is 0 and therefore operator precedence does not come into it. The parser does not treat , as the comma operator or = as the assignment operator; rather, these are grammatical parts of the declaration statement. Commented Mar 6, 2018 at 15:41
  • @EricLippert As far as precedence rules are concerned, that difference is irrelevant: Any C-style language I know uses the same precedences in a declaration as in other expressions. Anything else would invite desaster. Commented Mar 6, 2018 at 15:50
  • but programmers can be expected to know the precedence of the most used operators by heart, you say. In the example you give, I'm not sure most (average) programmers conceive of the member access operator or the array index operator as being operators in the mathematical sense at all, but instead think of them more as natural language nouns and the multiplication operator as the verb. That's why int i, j, k = 0; is such a fiendish construct, because it presents as the natural language analog of "int variables i, j, and k, are declared and shall be set to 0"!
    – Steve
    Commented Mar 6, 2018 at 20:56
  • @Steve How you remember the precedence rules as a programmer, is fully up to you. If it helps you to think of them as nouns of the language, do it. However, in that case you will run into problems when you see stuff like *a[i], I don't think you can sufficiently parse that with the "nouns" analogy. As for int i, j, k = 0;, that could mean anything if you don't look up the rules: A third interpretation would be to declare int i, then evaluate j and finally assign k = 0. Unless you know the syntax of your language, you cannot parse such constructs. It's your problem if you do anyway. Commented Mar 7, 2018 at 9:14
  • @cmaster, I wasn't expressing my specific memorisation strategy haha. I'm not a C programmer so my familiarity with operator precedence in C is second-rate. But what I noted when I looked at your example is that I didn't even think of the multiplication operator as having a relative precedence to the array index operator. That is, I didn't read a[i] as an index operator applied to a, but rather read both together as an irreducible syntactic element specifying the operand of the multiplication operator, and thus I wasn't even prompted to evaluate the precedence. (1/2)
    – Steve
    Commented Mar 7, 2018 at 11:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.