Is cast operator unary or binary? How many operands?

Discussion in 'C Programming' started by JoseMariaSola, Apr 29, 2008.

  1. How may operators and operands does (typename) expression has?

    I'd say one operator, the cast operator, and two operands: typename
    and expression.

    But everywhere I read, cast is categorized as an unary operator. Why
    is that? Is it just a syntax cotegory?

    Thanks.

    José María.
     
    JoseMariaSola, Apr 29, 2008
    #1
    1. Advertising

  2. JoseMariaSola

    Guest

    On Apr 29, 3:45 pm, JoseMariaSola <> wrote:
    > How may operators and operands does (typename) expression has?
    >
    > I'd say one operator, the cast operator, and two operands: typename
    > and expression.
    >
    > But everywhere I read, cast is categorized as an unary operator. Why
    > is that? Is it just a syntax cotegory?

    (typename)(expression) has one operator `(typename)' and one operand
    `(expression)'.
    The reason the type is enclosed in parentheses (as a design decision)
    is probably to avoid ambiguity, consider this:

    int i = 1; /* define and initialize i to 1 */
    {
    int i; /* cast i to int, a statement with no effect, or define i in
    block scope? */
    }
     
    , Apr 29, 2008
    #2
    1. Advertising

  3. > > I'd say one operator, the cast operator, and two operands: typename
    > > and expression.

    >
    > > But everywhere I read, cast is categorized as an unary operator. Why
    > > is that? Is it just a syntax cotegory?

    >
    > (typename)(expression) has one operator `(typename)' and one operand
    > `(expression)'.
    > The reason the type is enclosed in parentheses (as a design decision)
    > is probably to avoid ambiguity, consider this:
    >
    > int i = 1; /* define and initialize i to 1 */
    > {
    > int i; /* cast i to int, a statement with no effect, or define i in
    > block scope? */
    >
    > }


    Thanks, Vipps.

    According to your answeer, the operator '(typename)' is very
    particular, because it not a single token but three AND the middle
    token is anything an identifier may be.

    JM.
     
    JoseMariaSola, Apr 29, 2008
    #3
  4. On Apr 29, 1:47 pm, JoseMariaSola <> wrote:
    > > > I'd say one operator, the cast operator, and two operands: typename
    > > > and expression.

    >
    > > > But everywhere I read, cast is categorized as an unary operator. Why
    > > > is that? Is it just a syntax cotegory?

    >
    > > (typename)(expression) has one operator `(typename)' and one operand
    > > `(expression)'.
    > > The reason the type is enclosed in parentheses (as a design decision)
    > > is probably to avoid ambiguity, consider this:

    >
    > > int i = 1; /* define and initialize i to 1 */
    > > {
    > > int i; /* cast i to int, a statement with no effect, or define i in
    > > block scope? */

    >
    > > }

    >
    > Thanks, Vipps.
    >
    > According to your answeer, the operator '(typename)' is very
    > particular, because it not a single token but three AND the middle
    > token is anything an identifier may be.
    >
    > JM.


    The last line of my last post shoudl be:
    ... the middle token is anything an identifier may be and more.

    Here is part of the grammar:

    unary-expression:
    postfix-expression
    ++ unary-expression
    -- unary-expression
    unary-operator cast-expression
    sizeof unary-expression
    sizeof ( type-name )

    unary-operator: one of
    & * + - ˜ !

    cast-expression:
    unary-expression
    ( type-name ) cast-expression


    Why sizeof, (type-name), ++ and -- aren't unary-operators?

    Thanks.
     
    JoseMariaSola, Apr 29, 2008
    #4
  5. In article <>,
    JoseMariaSola <> wrote:

    >Here is part of the grammar:
    >
    >unary-expression:
    > postfix-expression
    > ++ unary-expression
    > -- unary-expression
    > unary-operator cast-expression
    > sizeof unary-expression
    > sizeof ( type-name )
    >
    >unary-operator: one of
    > & * + - ˜ !
    >
    >cast-expression:
    > unary-expression
    > ( type-name ) cast-expression
    >
    >
    >Why sizeof, (type-name), ++ and -- aren't unary-operators?


    You could include sizeof in unary-operator, but you'd still need the
    special case of a type-name operand requiring parentheses, and it
    seems clearer to keep them together in the list. Similarly ++ and --
    would still have to appear in postfix-expression. Both of these are
    just matters of taste really. I don't see how you could do
    (type-name), because a unary-operator is something that precedes its
    operand, and the parentheses of a cast have to go around the operand.

    -- Richard

    --
    :wq
     
    Richard Tobin, Apr 29, 2008
    #5
  6. On Apr 29, 2:18 pm, (Richard Tobin) wrote:
    > In article <>,
    >
    >
    >
    > JoseMariaSola <> wrote:
    > >Here is part of the grammar:

    >
    > >unary-expression:
    > > postfix-expression
    > > ++ unary-expression
    > > -- unary-expression
    > > unary-operator cast-expression
    > > sizeof unary-expression
    > > sizeof ( type-name )

    >
    > >unary-operator: one of
    > > & * + - ˜ !

    >
    > >cast-expression:
    > > unary-expression
    > > ( type-name ) cast-expression

    >
    > >Why sizeof, (type-name), ++ and -- aren't unary-operators?

    >
    > You could include sizeof in unary-operator, but you'd still need the
    > special case of a type-name operand requiring parentheses, and it
    > seems clearer to keep them together in the list. Similarly ++ and --
    > would still have to appear in postfix-expression. Both of these are
    > just matters of taste really.
    > I don't see how you could do
    > (type-name), because a unary-operator is something that precedes its
    > operand, and the parentheses of a cast have to go around the operand.


    But in the case of cast the (only) operand is the expression the left,
    not the type-name.

    Talking with you both I notice that every operator requires
    expressions as operands, and type-name is not an expression. Am I
    right?

    JM.
     
    JoseMariaSola, Apr 29, 2008
    #6
  7. JoseMariaSola <> writes:
    [...]
    > Talking with you both I notice that every operator requires
    > expressions as operands, and type-name is not an expression. Am I
    > right?


    Ideally, yes, but C is not an ideal language (not that I'm arguing it
    needs to be).

    "sizeof" is a unary operator; its operand can be either an expression
    (specifically a unary-expression) or a parenthesized type name.

    Or, if you prefer, "sizeof ( type-name )" is a special form of
    expression. You don't *have* to think of the parenthesized type name
    as an operand. But the standard puts it in the same section with the
    real unary operators, probably because the other form of "sizeof" is
    in that section. It would have been more logical, but less clear, to
    separate them.

    "." and "->" could be thought of as binary operators whose right
    operand is an identifier, but the standard treats them as postfix
    operators. Given:
    struct foo { int x; int y; };
    you can think of ".x" and ".y" as two distinct postfix operators, both
    applicable to operands of type "struct foo".

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Apr 29, 2008
    #7
  8. In article <>,
    JoseMariaSola <> wrote:

    >But in the case of cast the (only) operand is the expression the left,
    >not the type-name.


    I see, you want to consider, say, (int) as an operator with a single
    operand, rather than (int)x containing an operator with two operands,
    "int" and "x".

    This would imply an infinite number of operators, which is not
    out of the question but doesn't seem to offer any advantage.

    >Talking with you both I notice that every operator requires
    >expressions as operands, and type-name is not an expression. Am I
    >right?


    The two traditional uses of "( type-name )" - in casts and sizeof -
    and the new use in C99 - in compound literals - are indeed
    exceptional. I previously suggested that we could factor out

    type-expression:
    ( type-name )

    which would make sizeof in particular more regular:

    unary-expression:
    ...
    sizeof unary-expression
    sizeof type-expression

    -- Richard
    --
    :wq
     
    Richard Tobin, Apr 29, 2008
    #8
  9. On Apr 29, 5:31 pm, (Richard Tobin) wrote:
    > In article <>,
    >
    > JoseMariaSola  <> wrote:
    > >But in the case of cast the (only) operand is the expression the left,
    > >not the type-name.

    >
    > I see, you want to consider, say, (int) as an operator with a single
    > operand, rather than (int)x containing an operator with two operands,
    > "int" and "x".
    >
    > This would imply an infinite number of operators, which is not
    > out of the question but doesn't seem to offer any advantage.
    >
    > >Talking with you both I notice that every operator requires
    > >expressions as operands, and type-name is not an expression. Am I
    > >right?

    >
    > The two traditional uses of "( type-name )" - in casts and sizeof -
    > and the new use in C99 - in compound literals - are indeed
    > exceptional.  I previously suggested that we could factor out
    >
    >   type-expression:
    >      ( type-name )
    >
    > which would make sizeof in particular more regular:
    >
    >   unary-expression:
    >      ...
    >      sizeof unary-expression
    >      sizeof type-expression
    >
    > -- Richard
    > --
    > :wq


    Thanks, Richard.

    So both following expressions have one operator and one operand?
    sizeof(int)
    (int)x

    typename is considered an operand in the firs expressin but not in the
    second one?

    JM.
     
    JoseMariaSola, Apr 30, 2008
    #9
  10. In article <>,
    JoseMariaSola <> wrote:

    >> >But in the case of cast the (only) operand is the expression the left,
    >> >not the type-name.


    [...]

    >So both following expressions have one operator and one operand?
    > sizeof(int)
    > (int)x


    *I* dont' consider it that way. I was just exploring the consequences
    of your suggestion. I would say that they have one and two operands
    respectively.

    -- Richard
    --
    :wq
     
    Richard Tobin, Apr 30, 2008
    #10
  11. JoseMariaSola

    Chris Torek Guest

    In article <>
    JoseMariaSola <> wrote:
    >So both following expressions have one operator and one operand?
    > sizeof(int)
    > (int)x


    Yes.

    >typename is considered an operand in the firs expressin but not in the
    >second one?


    Yes. (In the second one, the type name is part of the operator.)

    This is just a matter of terminology, in this case, as applied to
    parsing. Since the terminology is made up by humans, it need not
    be entirely consistent, or even make all that much sense, as long
    as it lets one human communicate with another. :)

    The way to view this, to make sense out of it, is that the cast
    operator is inherently made up of the token sequence '(',
    type-name-keyword [%], ')'. Having consumed the type-name by this
    point, the only "argument" left to call an "operand" is the value
    being cast. The sizeof operator is inherently made up of the
    keyword token 'sizeof', and if its operand is a type-name, the
    type-name is syntactically required to have outer-level parentheses.
    Since the parentheses are (again) consumed by the syntax, the
    "argument" that is left, that can be called an "operand", is the
    type-name (without, in this case, the parentheses, although it
    makes no real difference anyway).

    [% In C as originally defined by Dennis Ritchie, "typedef" did not
    even exist. So all type names were keywords, which made parsing
    C easy. All declarations were instantly obvious, as they always
    started with a keyword, and since the total set of keywords was
    small, everyone knew all of them at a glance. When typedef was
    later added, some time in the late 1970s, the language became much
    more complicated syntactically, since typedef identifiers are only
    distinguishable from other identifiers by context. For instance,
    the C89 -- but not C99 -- code fragment:

    void f(x);

    can mean either:

    - declare f as function taking one argument of type int, and
    returning void; or

    - declare f as function taking one argument of type x, and
    returning void.

    The former makes use of C89's "implicit int"; the latter occurs if
    and only if "x" is a typedef-name. C99 removes this particular
    ambiguity by outlawing "implicit int", but other difficult parsing
    situations remain. From the parser's point of view, typedef-ed
    identifiers are "just like" keywords, except when they are not.
    If one attempts to use a conventional scanner and parser generator
    like (f)lex and (b)yacc, one must invent clever feedback and/or
    feed-forward mechanisms by which the parser can tell the lexer
    whether to claim a potential typedef name is a "type name" or an
    "identifier name". (Or one could use a more powerful parsing
    technique, but that means abandoning yacc.)

    Because it is impossible to tell at a glance whether some identifier
    is actually a typedef-name, C programmers often find themselves
    using some sort of self-imposed (or company coding standard imposed)
    typographic convention to "mark" all typedefs. For instance, some
    people use _t suffixes, so that it is clear that greeble_t is a
    type-name. Others use an initial capital letter, or all-uppercase.]
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: gmail (figure it out) http://web.torek.net/torek/index.html
     
    Chris Torek, Apr 30, 2008
    #11
  12. JoseMariaSola

    jacob navia Guest

    JoseMariaSola wrote:
    > How may operators and operands does (typename) expression has?
    >
    > I'd say one operator, the cast operator, and two operands: typename
    > and expression.
    >
    > But everywhere I read, cast is categorized as an unary operator. Why
    > is that? Is it just a syntax cotegory?
    >
    > Thanks.
    >
    > José María.


    It has one argument: the expression, and a *result*
    of type "typename"

    When I write

    (double)i;

    I am conceptually calling

    double TransformIntegerToDouble(int);

    a function that takes ONE integer argument and outputs
    a double number. Obviously there is no such a function
    since the compiler inlines this cast when compiling, but
    in some cases an actual function call will be generated.



    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
     
    jacob navia, Apr 30, 2008
    #12
  13. In article <>,
    Chris Torek <> wrote:

    >The way to view this, to make sense out of it, is that the cast
    >operator is inherently made up of the token sequence '(',
    >type-name-keyword [%], ')'.


    If you take this view, it makes more sense to say "... cast operators
    are inherently made up of ...", since even if (int) is an operator,
    it's clearly not the same operator as (double). The C standard seems
    to do this except in the index, where "cast operator, ( )" points to
    the section entitled "Cast operators".

    -- Richard
    --
    :wq
     
    Richard Tobin, Apr 30, 2008
    #13
  14. In article <fv9s2t$mu7$>, jacob navia <> wrote:

    >When I write
    >
    >(double)i;
    >
    >I am conceptually calling
    >
    >double TransformIntegerToDouble(int);


    Why are you not conceptually calling Transform(int, double)?

    -- Richard
    --
    :wq
     
    Richard Tobin, Apr 30, 2008
    #14
  15. JoseMariaSola

    jacob navia Guest

    Richard Tobin wrote:
    > In article <fv9s2t$mu7$>, jacob navia <> wrote:
    >
    >> When I write
    >>
    >> (double)i;
    >>
    >> I am conceptually calling
    >>
    >> double TransformIntegerToDouble(int);

    >
    > Why are you not conceptually calling Transform(int, double)?
    >
    > -- Richard


    Because the "int" is the RESULT type, not the input type!

    Besides, a hyper hyper generic procedure:
    Transform(anything,anything)
    is just a dream...

    You can have only concrete procedures:

    Something TransformToSomething(something_else);

    TransformIntegerToDouble exists (at least in lcc-win),
    and will take care of the details, correct rounding, etc etc.

    Transform(int,double) doesn't exist and can't exist since
    it would have to take ANY two input types and transform the
    second into the first, an impossible task!


    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
     
    jacob navia, Apr 30, 2008
    #15
  16. In article <fva02f$8jm$>, jacob navia <> wrote:


    >Besides, a hyper hyper generic procedure:
    > Transform(anything,anything)
    >is just a dream...


    Well, it's easily implementable:

    #define Transform(value, type) ((type)(value))

    >You can have only concrete procedures:


    You were the one who said "conceptually":

    >>> I am conceptually calling
    >>>
    >>> double TransformIntegerToDouble(int);


    Conceptually, you can have whatever you like.

    -- Richard
    --
    :wq
     
    Richard Tobin, Apr 30, 2008
    #16
  17. On 30 Apr 2008 13:10:55 GMT, Chris Torek <> wrote:

    > [% In C as originally defined by Dennis Ritchie, "typedef" did not
    > even exist. So all type names were keywords, which made parsing
    > C easy. All declarations were instantly obvious, as they always


    AIUI very early (Labs/pre-K&R1) C allowed file-scope declarations with
    no decl-specifiers at all, using implicit int AND implicit extern.
    This was still easy enough for humans to read, and to parse.

    > started with a keyword, and since the total set of keywords was
    > small, everyone knew all of them at a glance. When typedef was
    > later added, some time in the late 1970s, the language became much
    > more complicated syntactically, since typedef identifiers are only
    > distinguishable from other identifiers by context. For instance,
    > the C89 -- but not C99 -- code fragment:
    >
    > void f(x);
    >
    > can mean either:
    >
    > - declare f as function taking one argument of type int, and
    > returning void; or
    >
    > - declare f as function taking one argument of type x, and
    > returning void.
    >
    > The former makes use of C89's "implicit int"; the latter occurs if
    > and only if "x" is a typedef-name. <snip>


    A function _declaration_ can't have an identifier-list; it's either
    empty-parens () or a prototype. The difficulty occurs with a
    definition, and isn't actually ambiguous; but, as you say ...

    > <snip> From the parser's point of view, typedef-ed
    > identifiers are "just like" keywords, except when they are not.
    > If one attempts to use a conventional scanner and parser generator
    > like (f)lex and (b)yacc, one must invent clever feedback and/or
    > feed-forward mechanisms by which the parser can tell the lexer
    > whether to claim a potential typedef name is a "type name" or an
    > "identifier name". (Or one could use a more powerful parsing
    > technique, but that means abandoning yacc.)
    >

    Well, either the parser steers the lexer, or the lexer provides
    (typically additional/different) information which allows the parser
    to handle both possibilities. Either way it's a nuisance.

    - formerly david.thompson1 || achar(64) || worldnet.att.net
     
    David Thompson, May 12, 2008
    #17
    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. Anoob
    Replies:
    17
    Views:
    620
    Lawrence Kirby
    Dec 10, 2004
  2. muthu

    error: invalid operands to binary &

    muthu, Jul 17, 2006, in forum: C Programming
    Replies:
    4
    Views:
    1,139
    Keith Thompson
    Jul 17, 2006
  3. Richard Eich

    [?] invalid operands to binary &

    Richard Eich, Feb 5, 2007, in forum: C Programming
    Replies:
    1
    Views:
    631
    Richard Eich
    Feb 5, 2007
  4. SpOiLeR
    Replies:
    10
    Views:
    811
    SpOiLeR
    Oct 19, 2005
  5. Sheldon
    Replies:
    5
    Views:
    6,191
    Willem
    Nov 6, 2007
Loading...

Share This Page