Fornux C++ Superset - Forward Declarations of Nested Structures

255 views
Skip to first unread message

Phil Bouchard

unread,
May 1, 2018, 10:26:59 PM5/1/18
to ISO C++ Standard - Future Proposals
Greetings,

In the development of the "Fornux C++ Superset" source-to-source compiler and its Open Source memory manager counterpart "root_ptr":

Like previously mentioned I noticed the following problems with the C++ language:
- There is no distinction between a pointer and an iterator.
- There is no distinction between pointers to arrays of derived classes and pointers to arrays of base classes.

But I just realized the following also:
- The C++ language disallows top-level forward declarations of nested classes.

The latter becomes a problem if you want to, for example, specialize metadata template classes. Ex:

struct A
{
    struct B
    {};
};

The transpiler will generate:

struct A::B;

namespace metadata
{
    template <>
        struct construct<A::B>
        {
            template <typename... Args>
                A::B operator () (Args const &... args);
        };
}

But the problem is the following statement is not legal:
struct A::B;

So nested structures aren't commutative with template specializations which makes it impossible to generate metadata on-the-fly. The problem was always omnipresent but now it causes important problems in this case but also prevents further extensions of the language. 

It's just a matter of making C++ less strict in this case...


Regards,
-Phil

Richard Smith

unread,
May 2, 2018, 12:27:16 AM5/2/18
to std-pr...@isocpp.org
See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0289r0.pdf

The paper received some support from evolution. Some felt that the right answer was to wait for Modules. As noted in the above paper there are some open questions as to how this would actually work if we went forward with it.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cab4cada-1abe-48b2-9a4b-d6c9f994b805%40isocpp.org.

Phil Bouchard

unread,
May 2, 2018, 6:58:06 AM5/2/18
to ISO C++ Standard - Future Proposals


On Wednesday, May 2, 2018 at 12:27:16 AM UTC-4, Richard Smith wrote:
See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0289r0.pdf

The paper received some support from evolution. Some felt that the right answer was to wait for Modules. As noted in the above paper there are some open questions as to how this would actually work if we went forward with it.

1) I personally would consider the possibility of declaring pointers of nested classes based on the forward declaration of the aforementioned nested class at all times. Ex.:

class X;
struct X::A;

X::A * p = nullptr; // fine

1.1)
class X
{
}; // error caught here: missing class A

1.2)
class X
{
    struct A;
}; // error caught here: private member and already used as public


2) The same with template specializations:

class A;
struct A::B;

namespace metadata
{
    template <>
        struct construct<A::B>
        {
            template <typename... Args>
                A::B operator () (Args const &... args); // fine
        };
}

class A
{
    struct B
    {};

    void foo()
    {
        metadata::construct<B>()(); // fine: but could only be instanciated within this scope
    }
};

So pointer usages and template declarations of that nested class in question before its full declaration would have to be allowed. I would then define these error checks as "consistency checks".


Regards,
-Phil
 
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.

Phil Bouchard

unread,
May 2, 2018, 7:26:52 AM5/2/18
to ISO C++ Standard - Future Proposals


On Wednesday, May 2, 2018 at 6:58:06 AM UTC-4, Phil Bouchard wrote:


On Wednesday, May 2, 2018 at 12:27:16 AM UTC-4, Richard Smith wrote:
See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0289r0.pdf

The paper received some support from evolution. Some felt that the right answer was to wait for Modules. As noted in the above paper there are some open questions as to how this would actually work if we went forward with it.

1) I personally would consider the possibility of declaring pointers of nested classes based on the forward declaration of the aforementioned nested class at all times. Ex.:

class X;
struct X::A;

X::A * p = nullptr; // fine

1.1)
class X
{
}; // error caught here: missing class A

1.2)
class X
{
    struct A;
}; // error caught here: private member and already used as public

Unless we bring the notion of "partial declarations" and forward declarations of nested structures are made like this:

class X
{
    struct A;
    .... // ellipsis operator here
};

X::A * p = nullptr; // error

class X
{
    struct A;
    
    void foo()
    {
        X::A * p = nullptr; // fine
    }
};

This way that would solve the access scope problem cleanly.


Regards,
-Phil

Phil Bouchard

unread,
May 10, 2018, 7:03:36 PM5/10/18
to std-pr...@isocpp.org
On 05/02/2018 07:26 AM, Phil Bouchard wrote:
> Unless we bring the notion of "partial declarations" and forward
> declarations of nested structures are made like this:
>
> class X
> {
>     struct A;
>     .... // ellipsis operator here
> };
>
> X::A * p = nullptr; // error
>
> class X
> {
>     struct A;
>     void foo()
>     {
>         X::A * p = nullptr; // fine
>     }
> };
>
> This way that would solve the access scope problem cleanly.

Do we all agree this is a good solution? This could provide friend
declarations as well:

class X
{
friend struct A;

struct A;
.... // ellipsis operator here
};


Regards,
-Phil

Bengt Gustafsson

unread,
May 11, 2018, 10:30:34 AM5/11/18
to ISO C++ Standard - Future Proposals
I'm skeptical to partial declarations as the rules would be quite complicated. What I have found lacking on various occasions is the ability to declare inheritance in a forward declaration. Being able to declare inheritance relations early reduces the need of moving method implementations of methods out of the class head in certain situations.

When it comes to friend declarations it seems that you would not be helped by including them in a forward declaration as their sole purpose is to allow access to private members _which have not been declared yet_.

I would favor a proposal which includes your initial possibility to declare a nested class after declaring the outer class (or for consistence with namespace A::B { ... } without having to do so) plus the possibility to declare inheritance in a forward declaration.

Phil Bouchard

unread,
May 11, 2018, 1:51:19 PM5/11/18
to std-pr...@isocpp.org
Bengt Gustafsson <bengt.gu...@beamways.com> wrote:
> I'm skeptical to partial declarations as the rules would be quite
> complicated. What I have found lacking on various occasions is the ability
> to declare inheritance in a forward declaration. Being able to declare
> inheritance relations early reduces the need of moving method
> implementations of methods out of the class head in certain situations.
>
> When it comes to friend declarations it seems that you would not be helped
> by including them in a forward declaration as their sole purpose is to
> allow access to private members _which have not been declared yet_.
>
> I would favor a proposal which includes your initial possibility to declare
> a nested class after declaring the outer class (or for consistence with
> namespace A::B { ... } without having to do so) plus the possibility to
> declare inheritance in a forward declaration.

Ok so let’s forget about partial declarations and consider consistency
checks.

But regarding inheritance; there would be no way to see if classes are
virtual or not without their members. This would prevent us from using
dynamic_cast on pointers. Ex.:

struct Y;
struct X : Y;

Y * p = nullptr; // fine
X * q = dynamic_cast<X *>(p); // error

This might be an obscur use case but worth mentioning.


Regards,
-Phil

Reply all
Reply to author
Forward
0 new messages