[cfe-dev] Doubts about constructor calls (and functional casts).

Zhongxing Xu xuzhongxing at gmail.com
Mon Mar 22 23:13:24 PDT 2010


This strangeness looks to be cured:

code:

  A x = 3;
  A y = A(3);

now is parsed to:

(DeclStmt 0x32815f0 <line:10:3, col:10>
    0x32814e0 "A x =
      (CXXConstructExpr 0x3281580 <col:5, col:9> 'class A''void (class A
const &)' elidable
        (ImplicitCastExpr 0x3281540 <col:9> 'class A'
<ConstructorConversion>
          (CXXConstructExpr 0x3282760 <col:9> 'class A''void (int)'
            (IntegerLiteral 0x32827b0 <col:9> 'int' 3))))"
  (DeclStmt 0x3281640 <line:11:3, col:13>
    0x3280660 "A y =
      (ImplicitCastExpr 0x3281d60 <col:9, col:12> 'class A'
<ConstructorConversion>
        (CXXConstructExpr 0x3281cf0 <col:9, col:12> 'class A''void (class A
const &)' elidable
          (ImplicitCastExpr 0x3281cb0 <col:9, col:12> 'class A const' <NoOp>
            (CXXFunctionalCastExpr 0x3281c70 <col:9, col:12> 'class A'
functional cast to class A
              (CXXConstructExpr 0x3281c20 <col:9, col:11> 'class A''void
(int)'
                (IntegerLiteral 0x3281b60 <col:11> 'int' 3))))))")


2010/2/27 Enea Zaffanella <zaffanella at cs.unipr.it>

> Hello.
>
> I am a bit confused regarding the AST that is generated by clang++ when
> handling implicit/explicit calls to constructors. I would be grateful if
> someone would clarify a few points by going through the following examples.
>
>
> Let us consider the following struct definition:
> ==============
> struct S {
>   S(int);
> };
> ==============
> which is dumped by clang++ as follows (no surprise here):
> ==============
> struct S {
> public:
>     struct S;
>     S(int);
>     inline S(struct S const &);
>     inline struct S &operator=(struct S const &);
>     inline void ~S();
> };
> =============
>
>
> If I construct an S object using direct initialization
>     S s1(1);
> I get the following (which is what I am expecting):
> =============
>   (DeclStmt 0x1d5eba0 <line:6:3, col:10>
>     0x1d5ea60 "struct S s1 =
>       (CXXConstructExpr 0x1d5eb30 <col:5, col:8> 'struct S''void (int)'
>         (IntegerLiteral 0x1d5eac0 <col:8> 'int' 1))"
> =============
>
>
> If I now try with this variant
>      S s2 = 2;
> I get the following ... again, this is more or less what I was expecting:
> =============
>   (DeclStmt 0x1d5f1c0 <line:7:3, col:11>
>     0x1d5f000 "struct S s2 =
>       (CXXConstructExpr 0x1d5f150 <col:5, col:10> 'struct S''void
> (struct S const &)' elidable
>         (ImplicitCastExpr 0x1d5f110 <col:10> 'struct S'
> <ConstructorConversion>
>           (CXXConstructExpr 0x1d5f0a0 <col:10> 'struct S''void (int)'
>             (IntegerLiteral 0x1d5f060 <col:10> 'int' 2))))"
> =============
> I guess that the implicit cast between the two constructor calls is
> meant to convert the plain S type into a "const S&" type, so that it can
> be passed as an argument to the (elidable) copy constructor.
> Am I correct?
>
>
> But then I get to the following case
>     S s3 = S(3);
> for which I get the following AST:
> =============
>   (DeclStmt 0x1d5f430 <line:8:3, col:14>
>     0x1d5f1f0 "struct S s3 =
>       (ImplicitCastExpr 0x1d5f3f0 <col:10, col:13> 'struct S'
> <ConstructorConversion>
>         (CXXConstructExpr 0x1d5f380 <col:10, col:13> 'struct S''void
> (struct S const &)' elidable
>           (ImplicitCastExpr 0x1d5f340 <col:10, col:13> 'struct S const'
> <NoOp>
>             (CXXFunctionalCastExpr 0x1d5f300 <col:10, col:13> 'struct
> S' functional cast to struct S
>               (CXXConstructExpr 0x1d5f290 <col:10, col:12> 'struct
> S''void (int)'
>                 (IntegerLiteral 0x1d5f250 <col:12> 'int' 3))))))"
> =============
>
> Here there are two things that I do not understand.
>
> First, I cannot see why the result of the inner CXXConstructorExpr call
> should be fed to a CXXFunctionalCastExpr. I may agree that the
> initializer of s3 is a functional cast expression ... but then I would
> expect that the argument of this functional cast is the integer literal,
> not the struct S object returned by the constructor.
> In other words, to my eyes, the presence of the functional cast should
> exclude the presence of the inner constructor call, or vice versa.
> Is my reasoning missing some important point?
>
> Second, I cannot see why the result of the external (elidable) copy
> constructor call is (again) implicitly cast before being used as an
> initializer for s3. There seems to be no reason for such an implicit
> cast and, as a matter of fact, such a cast was not used in the previous
> example (when initializing s2).
>
> I would be grateful if someone either confirm my doubts or show to me
> where is the gap in my reasoning.
>
> Regards,
> Enea Zaffanella.
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100323/6cd9bf13/attachment.html>


More information about the cfe-dev mailing list