A question on variable declarations/initializations

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andreas Wachowski

    A question on variable declarations/initializations

    Hi,

    consider the following program:

    // --------------
    class A
    {
    public:
    A(int i) { }
    };

    class B
    {
    public:
    B(const A&) { }
    void f(int) const { }
    };

    int main()
    {
    int i(1);

    // Declaring a variable v of type B, initialized with A(i):
    B v(A(i)); // Nope, this is not producing the intended behaviour, see
    error messages below
    // Working alternatives:
    // 1) B v((A)(i));
    // 2) B v(i);
    // 3) B v(1);
    // 4) B v = B(A(i));

    v.f(i); // Sun Workshop 5.2: B(*)(A) is not a structure type
    // GCC 3.3.1: request for member b in b(A), which
    // is of non-aggregate type B()(A)

    return 0;
    }

    // --------------

    As far as I understand, "B v(A(i));" is interpreted as a "pointer v to a
    function taking a parameter of type A and returning B". In that case,
    naturally, f cannot be called on v.

    I don't understand, however, why "B v(A(i));" shouldn't equally well be seen
    as "variable v of type B, initialized with the temporary A(i)". For example,
    what's the difference to alternative 1), "B v((A)(i));" ?

    Do I miss something trivial? I would appreciate if someone could elaborate
    in detail on how this declaration is interpreted.

    Many thanks,
    Andreas


  • Gianni Mariani

    #2
    Re: A question on variable declarations/initializations

    Andreas Wachowski wrote:[color=blue]
    > Hi,
    >
    > consider the following program:
    >
    > // --------------
    > class A
    > {
    > public:
    > A(int i) { }
    > };
    >
    > class B
    > {
    > public:
    > B(const A&) { }
    > void f(int) const { }
    > };
    >
    > int main()
    > {
    > int i(1);
    >
    > // Declaring a variable v of type B, initialized with A(i):
    > B v(A(i)); // Nope, this is not producing the intended behaviour, see
    > error messages below
    > // Working alternatives:
    > // 1) B v((A)(i));
    > // 2) B v(i);
    > // 3) B v(1);
    > // 4) B v = B(A(i));
    >
    > v.f(i); // Sun Workshop 5.2: B(*)(A) is not a structure type
    > // GCC 3.3.1: request for member b in b(A), which
    > // is of non-aggregate type B()(A)
    >
    > return 0;
    > }
    >
    > // --------------
    >
    > As far as I understand, "B v(A(i));" is interpreted as a "pointer v to a
    > function taking a parameter of type A and returning B". In that case,
    > naturally, f cannot be called on v.
    >
    > I don't understand, however, why "B v(A(i));" shouldn't equally well be seen
    > as "variable v of type B, initialized with the temporary A(i)". For example,
    > what's the difference to alternative 1), "B v((A)(i));" ?
    >
    > Do I miss something trivial? I would appreciate if someone could elaborate
    > in detail on how this declaration is interpreted.[/color]

    For whatever reason, v is being interpeted as a function declaration
    returning a B.

    error from gcc:
    request for member `f' in `v', which is of non-class type `B ()(A)'

    Comeau gives a similar error.

    The interesting thing is that this also works as you expect:

    B v(A(1));

    I don't understand how A(i) can be considered a type and not an
    expression, or even that A(1) is an expression not when A(i) is not.
    Also given that 3 compilers all seem to agree, I am a bit perplexed.


    Comment

    • Rolf Magnus

      #3
      Re: A question on variable declarations/initializations

      Gianni Mariani wrote:
      [color=blue]
      > Andreas Wachowski wrote:[color=green]
      >> Hi,
      >>
      >> consider the following program:
      >>
      >> // --------------
      >> class A
      >> {
      >> public:
      >> A(int i) { }
      >> };
      >>
      >> class B
      >> {
      >> public:
      >> B(const A&) { }
      >> void f(int) const { }
      >> };
      >>
      >> int main()
      >> {
      >> int i(1);
      >>
      >> // Declaring a variable v of type B, initialized with A(i):
      >> B v(A(i)); // Nope, this is not producing the intended behaviour,
      >> see
      >> error messages below
      >> // Working alternatives:
      >> // 1) B v((A)(i));
      >> // 2) B v(i);
      >> // 3) B v(1);
      >> // 4) B v = B(A(i));
      >>
      >> v.f(i); // Sun Workshop 5.2: B(*)(A) is not a structure type
      >> // GCC 3.3.1: request for member b in b(A), which
      >> // is of non-aggregate type B()(A)
      >>
      >> return 0;
      >> }
      >>
      >> // --------------
      >>
      >> As far as I understand, "B v(A(i));" is interpreted as a "pointer v
      >> to a function taking a parameter of type A and returning B". In that
      >> case, naturally, f cannot be called on v.
      >>
      >> I don't understand, however, why "B v(A(i));" shouldn't equally well
      >> be seen as "variable v of type B, initialized with the temporary
      >> A(i)". For example, what's the difference to alternative 1), "B
      >> v((A)(i));" ?
      >>
      >> Do I miss something trivial? I would appreciate if someone could
      >> elaborate in detail on how this declaration is interpreted.[/color]
      >
      > For whatever reason, v is being interpeted as a function declaration
      > returning a B.
      >
      > error from gcc:
      > request for member `f' in `v', which is of non-class type `B
      > ()(A)'
      >
      > Comeau gives a similar error.
      >
      > The interesting thing is that this also works as you expect:
      >
      > B v(A(1));
      >
      > I don't understand how A(i) can be considered a type and not an
      > expression,[/color]

      B v(A(i)) declares a funcion named v that takes as a parameter named i
      an object of type A and returns an object of type B. It's equivalent
      to:

      B v(A i)
      [color=blue]
      > or even that A(1) is an expression not when A(i) is not.[/color]

      1 can't be the name of a parameter, but i can.

      Comment

      • Andreas Wachowski

        #4
        Re: A question on variable declarations/initializations

        "Rolf Magnus" <ramagnus@t-online.de> wrote in message
        news:cfod96$cnr $01$1@news.t-online.com...

        [snip]
        [color=blue]
        > B v(A(i)) declares a funcion named v that takes as a parameter named i
        > an object of type A and returns an object of type B. It's equivalent
        > to:
        >
        > B v(A i)
        >[/color]

        So far, so good; thanks for the answer. I am still surprised, though, I
        don't think I have seen this before. Can someone point me to a section in
        the standard (or some book or other source) explaining this, perhaps? How
        can one know (i.e. without relying on the compiler's error message) that the
        statement "B v(A(i))" will not declare an element v of type B, initialized
        with A(i)?

        Your help is appreciated!

        Thanks in advance, Andreas


        Comment

        • Ron Natalie

          #5
          Re: A question on variable declarations/initializations


          "Andreas Wachowski" <andreas.wachow ski@gmx.de> wrote in message news:2ob3k7F87p d2U1@uni-berlin.de...
          [color=blue]
          > So far, so good; thanks for the answer. I am still surprised, though, I
          > don't think I have seen this before. Can someone point me to a section in
          > the standard (or some book or other source) explaining this, perhaps? How
          > can one know (i.e. without relying on the compiler's error message) that the
          > statement "B v(A(i))" will not declare an element v of type B, initialized
          > with A(i)?
          >[/color]
          It's amplified in section 8.2 of the standard (Ambiguity Resolution). The rule
          that when there is an ambiguity between a declaration and an expression, the
          declaration wins out.

          The ambiguity is if A(i) is a declaration of the parameter i of type A, or a cast
          expression A(i), it is resolved as the declaration.

          -Ron

          Comment

          • jeffc

            #6
            Re: A question on variable declarations/initializations


            "Ron Natalie" <ron@sensor.com > wrote in message
            news:4120b236$0 $2486$9a6e19ea@ news.newshostin g.com...[color=blue][color=green]
            > >[/color]
            > It's amplified in section 8.2 of the standard (Ambiguity Resolution).[/color]
            The rule[color=blue]
            > that when there is an ambiguity between a declaration and an expression,[/color]
            the[color=blue]
            > declaration wins out.
            >
            > The ambiguity is if A(i) is a declaration of the parameter i of type A, or[/color]
            a cast[color=blue]
            > expression A(i), it is resolved as the declaration.[/color]

            It never even occured to me this could be ambiguous, because I didn't know
            you could declare parameters this way. Am I missing something basic, or
            obscure?


            Comment

            • Rolf Magnus

              #7
              Re: A question on variable declarations/initializations

              jeffc wrote:
              [color=blue][color=green]
              >> The ambiguity is if A(i) is a declaration of the parameter i of type
              >> A, or a cast expression A(i), it is resolved as the declaration.[/color]
              >
              > It never even occured to me this could be ambiguous, because I didn't
              > know you could declare parameters this way. Am I missing something
              > basic, or obscure?[/color]

              You're missing that if you declare something like:

              A (i);

              the parens are superfluous and ignored.

              Comment

              Working...