Velocity Reviews > historical question, C unary operators

# historical question, C unary operators

mathog
Guest
Posts: n/a

 03-29-2012
C has a very small number of unary operators that change the value of
the variable they operate on. (What is the technical name for unary
operators that do this?) These are:

i++, ++i, i--, --i

Most unary operators in C do not change the value of the variable, like:

result = 1 + -var;
if(!var){

Anyway, does anybody know historically why they went with ++ for
increment instead of using a more general and extensible form like

<variable><unary indicator><operator> postfix form
<operator><unary indicator><variable> prefix form

where if "@" had indicated unary operators of this type, then "postfix
increment" would have been:

i@+

???

This came up in the context of a discussion on C99 bool, where the
expected "in place" unary operator "!!" is not available because

!!var

already has a meaning in C (and one that does not change the value of
var), leaving no space for an "in place" unary variant that would have
negated the value of var. Had the language employed an extensible form
then when C99 came along with the bool type it would have been simple to

!@var;

equivalent to

var != var;

Thanks,

David Mathog

Stefan Ram
Guest
Posts: n/a

 03-29-2012
mathog <(E-Mail Removed)> writes:
>!!var
>!@var

»@« means having to add meaningless garbage in 99 % of the cases
just to save a single characters in 1 % of the cases
»v=!!v«).

In some languages there really is an »@«. It's call »apply«, e.g.:

APPLY f,x

Thomas Richter
Guest
Posts: n/a

 03-29-2012
On 29.03.2012 20:18, mathog wrote:
> C has a very small number of unary operators that change the value of
> the variable they operate on. (What is the technical name for unary
> operators that do this?) These are:
>
> i++, ++i, i--, --i

> Anyway, does anybody know historically why they went with ++ for
> increment instead of using a more general and extensible form

To my very knowledge, the reason why ++ and -- were added to the
language was mostly because these operations were supported by the
hardware platform (IIRC, a PDP) C was first written for. So for example,
an expression like "*p++ = j" translates directly to one single
instruction on a PDP to my knowledge. (For the 68K, this would be a
"move.x dx,(ax)+", simply). There is no hardware shortcut for anything
else, i.e. not for !!, ^^, ** or //, so the operators did not became
part of C. The syntax pretty much expressed the "high level assembly"
approach C took.

Probably others may comment whether my speculations are correct.

So long,
Thomas

Kaz Kylheku
Guest
Posts: n/a

 03-30-2012
On 2012-03-29, mathog <(E-Mail Removed)> wrote:
> C has a very small number of unary operators that change the value of
> the variable they operate on. (What is the technical name for unary
> operators that do this?)

"munary": mutating unary.

Just kidding.

> i++, ++i, i--, --i

Only in ++i and --i are the operators called unary. In i-- and i++,
the operator is called a postfix operator, not unary. Postfix + and -
do not exist: i+; and i-; are syntax errors.

> Anyway, does anybody know historically why they went with ++ for
> increment instead of using a more general and extensible form like
>
> <variable><unary indicator><operator> postfix form
> <operator><unary indicator><variable> prefix form

I think you might mean "destructive indicator". (You wouldn't rewrite the unary
minus -x as -@x right? Only --x as -@x, surely.)

> where if "@" had indicated unary operators of this type, then "postfix
> increment" would have been:
>
> i@+

As an aside, the @ character does not occur in C; which is why Objective C is
able to use it to denote extensions without breaking compatibility with C.

In early versions of C (B, NB?) ++ was separate tokens, so it was possible
to write i + +.

Floating point + was written #+. So there was some of this kind of prefixing
going on; the trend obviously was to remove it.

It was not in their taste to have that kind of thing going on.

> This came up in the context of a discussion on C99 bool, where the
> expected "in place" unary operator "!!" is not available because

Expected? By whom? Never occured to me, for one.

Flipping a value is rare compared to incrementing.

Do you expect x to be flipped to its reciprocal by //x?

According to this pattern, --x should flip x to its additive inverse,
rather than decrement it. That is what would relate the meaning of
--x to the unary -x. And of course ++x should do nothing because +x does nothing.

So the idea that !!x toggles x is not consistent with --x or ++x in any way
other than the very weak idea that a double-character operator modifes the
operand in some way which is related to what the single-character unary
operator does.

Basically, Ritchie assigned the doubled-up tokens in ways that were
semantically sensible rather than playing up to some "extensible" lexical
consistencies. He didn't think too much, which is why he gave & a high
precedence and && a low precedence.

The C language is not extensible. You can't write your own operators without
hacking the compiler.

If you want really extensible operators, playing little games with characters
in the tokens isn't a good way to achieve it.

Eric Sosman
Guest
Posts: n/a

 03-30-2012
On 3/29/2012 2:18 PM, mathog wrote:
> C has a very small number of unary operators that change the value of
> the variable they operate on. (What is the technical name for unary
> operators that do this?) These are:
>
> i++, ++i, i--, --i
>
> Most unary operators in C do not change the value of the variable, like:
>
> result = 1 + -var;
> if(!var){

Furthermore, most binary operators do not change the value of
any operand, the exceptions being = and op=.

Still more furthermore more, most ternary operators do not
change the value of any operand.

Summarizing: "Most operators leave their operands alone, but a
few may alter them." Are you uncomfortable with that?

> Anyway, does anybody know historically why they went with ++ for
> increment instead of using a more general and extensible form like
>
> <variable><unary indicator><operator> postfix form
> <operator><unary indicator><variable> prefix form
>
> where if "@" had indicated unary operators of this type, then "postfix
> increment" would have been:
>
> i@+

Okay, what should @% do?

For ++ and -- there are fairly natural ideas about what the
implied missing operand could be. In English we even have special
words for these ideas: "next" and "previous," or "successor" and
"predecessor." What's the corresponding natural notion for %?

Ooh, even better: What should @* do as a *prefix* operator?
The prefix * means "my operand is a pointer; follow it to the
pointee," so @* ought to mean "...and then assign the pointee's
value to my operand." But you can't assign a T value to a T*
variable, so @*ptr would have to mean "issue a diagnostic."
Which, in fact, it already does -- so your wish is granted!

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d

Eric Sosman
Guest
Posts: n/a

 03-30-2012
On 3/29/2012 2:54 PM, Thomas Richter wrote:
>[...]
> To my very knowledge, the reason why ++ and -- were added to the
> language was mostly because these operations were supported by the
> hardware platform (IIRC, a PDP) C was first written for. [...]

Somebody with the initials DMR disagrees with you. He's not in
a position to contradict you at this moment, but you can find out for
yourself that he has already done so. Search for an article called
"The Development of the C Language" and within that article look for
the text string "PDP-11". GIYF.

--
Eric Sosman
(E-Mail Removed)d

mathog
Guest
Posts: n/a

 03-30-2012
Eric Sosman wrote:

> Summarizing: "Most operators leave their operands alone, but a
> few may alter them." Are you uncomfortable with that?

Sure.

All languages have at least one assignment operator, why did C need
more? C already had a way to write "increment" using only one instance
of the variable:

i+=1;

so why invent

i++;

which saves a grand total of one character?

Letting ++ and -- change the value of its operand was not purely a
blessing, it made it relatively easy to write indeterminate code, as in:

i=i++;

and these used to be a real plague before the compilers became smart
enough to catch code like that.

Did K or R ever explain what the problem was they were addressing that
led them to add to the languge ++ and -- not just as unary
increment/decrement, but also changing the operand's value? The one
thing I can think of that might have induced them to do so was that it
made it possible to use while() and do/while() in instances where
otherwise for() would have been needed, like:

while(*ptr++){

for(; *ptr; ptr+=1){

The first form is more compact, but of course they do the same thing.

Regards,

David Mathog

Richard Damon
Guest
Posts: n/a

 03-30-2012
On 3/30/12 12:16 PM, mathog wrote:
> Eric Sosman wrote:
>
>> Summarizing: "Most operators leave their operands alone, but a
>> few may alter them." Are you uncomfortable with that?

>
> Sure.
>
> All languages have at least one assignment operator, why did C need
> more? C already had a way to write "increment" using only one instance
> of the variable:
>
> i+=1;
>
> so why invent
>
> i++;
>
> which saves a grand total of one character?
>
> Letting ++ and -- change the value of its operand was not purely a
> blessing, it made it relatively easy to write indeterminate code, as in:
>
> i=i++;
>
> and these used to be a real plague before the compilers became smart
> enough to catch code like that.
>
> Did K or R ever explain what the problem was they were addressing that
> led them to add to the languge ++ and -- not just as unary
> increment/decrement, but also changing the operand's value? The one
> thing I can think of that might have induced them to do so was that it
> made it possible to use while() and do/while() in instances where
> otherwise for() would have been needed, like:
>
> while(*ptr++){
>
>
> for(; *ptr; ptr+=1){
>
> The first form is more compact, but of course they do the same thing.
>
> Regards,
>
> David Mathog
>
>

i+=1 and i++ are NOT equivalent if you are using the value of to expression.

A common use if this would be something like

*(ptr++) = chr;

which puts the character into the current location in the buffer and
then increments the index. This may be more efficient than

*ptr = chr;
ptr += i;

in that the first give the compiler the hint that it might want to use
an automatic post increment instruction, while the second requires the
compiler to figure this out itself (early compilers did not always do a
great job of optimizing).

You could not use

*(ptr += 1) = chr;

as that stores chr in the wrong place.

If the original code was *++ptr = chr; then you could do this, but that
requires (typically) initializing ptr to one place before the beginning
of your buffer, which was not promised to be creatable as a pointer.

Ben Pfaff
Guest
Posts: n/a

 03-30-2012
mathog <(E-Mail Removed)> writes:

> All languages have at least one assignment operator, why did C need
> more? C already had a way to write "increment" using only one instance
> of the variable:
>
> i+=1;
>
> so why invent
>
> i++;
>
> which saves a grand total of one character?

i+=1 and i++ have different values. This can be significant when
one of them is incorporated into a larger expression.

On the other hand, I can't think of many significant difference
between i+=1 and ++i. Spelling is one. Precedence is another:
in some contexts, i+=1 would require parentheses but i++ would
not.

Many coding styles put spaces around binary operators, so that
i++ saves three characters over "i += 1".
--
Ben Pfaff
http://benpfaff.org

Stefan Ram
Guest
Posts: n/a

 03-30-2012
mathog <(E-Mail Removed)> writes:
>so why invent
>i++;
>which saves a grand total of one character?

»++i« is easier to comprehend (more readable), because it
confirms with the two word sentence »increment i«. More
words require more brain spaces and thus less fits in.

http://en.wikipedia.org/wiki/Working_memory#Capacity
http://en.wikipedia.org/wiki/Chunking_(psychology)
http://en.wikipedia.org/wiki/The_Mag...s_or_Minus_Two

»Remember: programming languages exist for humans to
read and understand easier, not for machines.«

http://blog.jovan-s.com/2009/07/23/t...ing-standards/

»Code is for humans. Code is written once, read many times.«

http://idldoc.idldev.com/attachment/...pdf?format=raw

»[A] program is a paper in a formal language written /for

http://cs.wellesley.edu/~cs249/Resou...-standard.html

»Write the code /for humans/ to read and understand easily.«

http://particletree.com/features/suc...mmenting-code/