historical question, C unary operators

Discussion in 'C Programming' started by mathog, Mar 29, 2012.

  1. mathog

    mathog Guest

    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
    add:

    !@var;

    equivalent to

    var != var;

    Thanks,

    David Mathog
    mathog, Mar 29, 2012
    #1
    1. Advertising

  2. mathog

    Stefan Ram Guest

    mathog <> 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« instead of
    »v=!!v«).

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

    APPLY f,x
    Stefan Ram, Mar 29, 2012
    #2
    1. Advertising

  3. 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
    Thomas Richter, Mar 29, 2012
    #3
  4. mathog

    Kaz Kylheku Guest

    On 2012-03-29, 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?)


    "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.
    Kaz Kylheku, Mar 30, 2012
    #4
  5. mathog

    Eric Sosman Guest

    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
    d
    Eric Sosman, Mar 30, 2012
    #5
  6. mathog

    Eric Sosman Guest

    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
    d
    Eric Sosman, Mar 30, 2012
    #6
  7. mathog

    mathog Guest

    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++){

    instead of

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

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

    Regards,

    David Mathog
    mathog, Mar 30, 2012
    #7
  8. 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++){
    >
    > instead of
    >
    > 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.
    Richard Damon, Mar 30, 2012
    #8
  9. mathog

    Ben Pfaff Guest

    mathog <> 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
    Ben Pfaff, Mar 30, 2012
    #9
  10. mathog

    Stefan Ram Guest

    mathog <> 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.
    Read:

    http://en.wikipedia.org/wiki/Working_memory#Capacity
    http://en.wikipedia.org/wiki/Chunking_(psychology)
    http://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_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/there-are-no-reasons-to-not-follow-coding-standards/

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

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

    »[A] program is a paper in a formal language written /for
    humans/ to read.«

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

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

    http://particletree.com/features/successful-strategies-for-commenting-code/
    Stefan Ram, Mar 30, 2012
    #10
  11. "Scott Fluhrer" <> writes:

    > "Eric Sosman" <> wrote in message
    > news:jl31u2$12i$...
    >> [...] But you can't assign a T value to a T*
    >> variable, so @*ptr would have to mean "issue a diagnostic."

    <snip>

    > /* From the Nits-R-Us department */
    > int main(void) {
    > void (*var)(void) = 0;
    >
    > var = *var; /* Hey! No diagnostics! */
    > return 0;
    > }
    > /* Admittedly, that line, while legal, wasn't that useful... :) */


    From the under-janitor in that department...

    var = *var

    does not attempt to assign a T value to a T* variable :)

    --
    Ben.
    Ben Bacarisse, Mar 30, 2012
    #11
  12. mathog

    Eric Sosman Guest

    On 3/30/2012 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;


    If you're comfortable with the escalation from = as the only
    assignment operator to a C with seven such operators (=, +=, -=,
    *=, /=, %=, <<=, >>=), it seems strange that adding four more
    (++, --, ++, --) would cause discomfort. (Besides, these four
    are not "assignment" operators.)

    Also, didn't you suggest that something like @op would have
    been a better choice, allowing the introduction of even more
    "assignment" operators?

    > so why invent
    >
    > i++;
    >
    > which saves a grand total of one character?


    For one thing, the effect of `x = i++' and `x = i += 1' is
    noticeably different. To get the effect of the former, you'd need to
    write something like `x = i, i += 1' and the "grand total" comes
    up short.

    For another, consider expressions with multiple operators, where
    precedence comes into play (I'll stick with prefix versions to avoid
    the point already raised):

    x = ++i * r;
    x = i += 1 * r;

    To fix the second, you'd need to add a set of parentheses:

    x = (i += 1) * r;

    .... and again, the "grand total" understates the actuality.

    > 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.


    Have you considered `i = i = i = i'? No increments or decrements
    or anything of the kind, yet the behavior is nonetheless undefined.
    I don't think you can blame U.B. on auto-increment and auto-decrement.

    > 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?


    It was T, actually. The paper has been cited elsethread, but
    it doesn't say much about motivation. K&R describe the operators
    as "more concise and often more efficient;" the efficiency claim is
    now badly dated, but conciseness remains.

    > 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++){
    >
    > instead of
    >
    > for(; *ptr; ptr+=1){
    >
    > The first form is more compact, but of course they do the same thing.


    They do *not* do the same thing. Is it time to reacquaint
    yourself with your C textbook?

    --
    Eric Sosman
    d
    Eric Sosman, Mar 30, 2012
    #12
  13. mathog

    Eric Sosman Guest

    On 3/30/2012 2:05 PM, Eric Sosman wrote:
    > On 3/30/2012 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;

    >
    > If you're comfortable with the escalation from = as the only
    > assignment operator to a C with seven such operators (=, +=, -=,
    > *=, /=, %=, <<=, >>=), it seems strange that adding four more
    > (++, --, ++, --) would cause discomfort.[...]


    Sorry: I overlooked &=, |=, and ^=. To restate: If expansion
    from one assignment operator to TEN doesn't disturb you, it seems
    strange that adding four more makes you suddenly uncomfortable.

    --
    Eric Sosman
    d
    Eric Sosman, Mar 30, 2012
    #13
  14. mathog

    Eric Sosman Guest

    On 3/30/2012 2:39 PM, Scott Fluhrer wrote:
    > "Eric Sosman"<> wrote in message
    > news:jl4t05$c62$...
    >> On 3/30/2012 2:05 PM, Eric Sosman wrote:
    >>>
    >>> If you're comfortable with the escalation from = as the only
    >>> assignment operator to a C with seven such operators (=, +=, -=,
    >>> *=, /=, %=,<<=,>>=), it seems strange that adding four more
    >>> (++, --, ++, --) would cause discomfort.[...]

    >>
    >> Sorry: I overlooked&=, |=, and ^=. To restate: If expansion
    >> from one assignment operator to TEN doesn't disturb you, it seems
    >> strange that adding four more makes you suddenly uncomfortable.

    >
    > Actually, you might want to count them again; =, +=, -=, *=, /=, %=,<<=,
    > >>=,&=, |=, ^= make a total of ELEVEN operators...


    (Sigh.)

    "The square root of six is three, for suitable values of three."

    --
    Eric Sosman
    d
    Eric Sosman, Mar 30, 2012
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ruben Campos
    Replies:
    5
    Views:
    546
    Ruben Campos
    Nov 30, 2004
  2. Ashwin  N

    Associativity of unary operators

    Ashwin N, Sep 8, 2006, in forum: Java
    Replies:
    4
    Views:
    1,693
    Stefan Ram
    Sep 9, 2006
  3. dspfun

    Associativity of unary C Operators

    dspfun, Jan 1, 2007, in forum: C Programming
    Replies:
    28
    Views:
    869
    CBFalconer
    Jan 5, 2007
  4. SpOiLeR
    Replies:
    10
    Views:
    797
    SpOiLeR
    Oct 19, 2005
  5. JanW
    Replies:
    2
    Views:
    312
    Gennaro Prota
    Oct 3, 2008
Loading...

Share This Page