public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/111923] New: default argument is not treated as a complete-class context of a class
@ 2023-10-22 22:42 stsp at users dot sourceforge.net
  2023-10-22 22:51 ` [Bug c++/111923] " pinskia at gcc dot gnu.org
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: stsp at users dot sourceforge.net @ 2023-10-22 22:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

            Bug ID: 111923
           Summary: default argument is not treated as a complete-class
                    context of a class
           Product: gcc
           Version: 13.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: stsp at users dot sourceforge.net
  Target Milestone: ---

The standard says:

https://eel.is/c++draft/class.mem.general#7.2

A complete-class context of a class (template) is a

    (7.1)function body ([dcl.fct.def.general]),
    (7.2)default argument ([dcl.fct.default]),
...
[Note 4: A complete-class context of a nested class is also a complete-class
context of any enclosing class, if the nested class is defined within the
member-specification of the enclosing class.
— end note]


I think this means that the following
code should compile:

struct A {
    char a;
    static constexpr int (*off_p)(int p) =
        [](int off = offsetof(A, a)) static constexpr ->int { return off; };
};

But it fails with:

bad.cpp:6:22: error: invalid use of incomplete type ‘struct A’

Surprisingly, this code does actually compile:

struct A {
    char a;
    int (*off_p)(int p) =
        [](int off = offsetof(A, a)) static constexpr ->int { return off; };
};

(the only difference is that off_p
is no longer static constexpr).
But I need this code to compile when
off_p is a static constexpr.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
@ 2023-10-22 22:51 ` pinskia at gcc dot gnu.org
  2023-10-22 22:56 ` pinskia at gcc dot gnu.org
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-10-22 22:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
clang rejects it for the same reason ...

So does MSVC .

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
  2023-10-22 22:51 ` [Bug c++/111923] " pinskia at gcc dot gnu.org
@ 2023-10-22 22:56 ` pinskia at gcc dot gnu.org
  2023-10-22 22:58 ` pinskia at gcc dot gnu.org
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-10-22 22:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
For the non-static case, "default member initializer" applies.

That is:
```
#include <cstddef>
struct A {
    char a;
    static constexpr int off_p = offsetof(A, a);
};
```

is illformed too.

But
```
#include <cstddef>
struct A {
    char a;
    int off_p = offsetof(A, a);
};
```
is well formed due to it being a DMI.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
  2023-10-22 22:51 ` [Bug c++/111923] " pinskia at gcc dot gnu.org
  2023-10-22 22:56 ` pinskia at gcc dot gnu.org
@ 2023-10-22 22:58 ` pinskia at gcc dot gnu.org
  2023-10-22 23:04 ` stsp at users dot sourceforge.net
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-10-22 22:58 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
One more note, default argument clause does not apply here as the it is not an
argument of a method of that class but rather a different context (the lamdba
definition context).

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
                   ` (2 preceding siblings ...)
  2023-10-22 22:58 ` pinskia at gcc dot gnu.org
@ 2023-10-22 23:04 ` stsp at users dot sourceforge.net
  2023-10-22 23:08 ` pinskia at gcc dot gnu.org
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: stsp at users dot sourceforge.net @ 2023-10-22 23:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

--- Comment #4 from Stas Sergeev <stsp at users dot sourceforge.net> ---
(In reply to Andrew Pinski from comment #3)
> One more note, default argument clause does not apply here as the it is not
> an argument of a method of that class but rather a different context (the
> lamdba definition context).

Yes, but doesn't this apply to the note4?
[Note 4: A complete-class context of a nested class is also a complete-class
context of any enclosing class, if the nested class is defined within the
member-specification of the enclosing class.
— end note]

Isn't lambda an instance of a nested class here?

> int off_p = offsetof(A, a);
> is well formed due to it being a DMI.

Thanks for info.
Do you happen to know the particular reason
why the standard disallows this for static
member? Shouldn't that be a DR?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
                   ` (3 preceding siblings ...)
  2023-10-22 23:04 ` stsp at users dot sourceforge.net
@ 2023-10-22 23:08 ` pinskia at gcc dot gnu.org
  2023-10-22 23:27 ` stsp at users dot sourceforge.net
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-10-22 23:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

--- Comment #5 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Stas Sergeev from comment #4)
> (In reply to Andrew Pinski from comment #3)
> > One more note, default argument clause does not apply here as the it is not
> > an argument of a method of that class but rather a different context (the
> > lamdba definition context).
> 
> Yes, but doesn't this apply to the note4?
> [Note 4: A complete-class context of a nested class is also a complete-class
> context of any enclosing class, if the nested class is defined within the
> member-specification of the enclosing class.
> — end note]
> 
> Isn't lambda an instance of a nested class here?

Nope, lamdba's are not a nested class.

> 
> > int off_p = offsetof(A, a);
> > is well formed due to it being a DMI.
> 
> Thanks for info.
> Do you happen to know the particular reason
> why the standard disallows this for static
> member? Shouldn't that be a DR?

Considering all compilers agree, it is not usually a defect report.
I also don't see how this would work in really because you could use a `static
constexpr` as an size for an array.

That is:
```
#include <cstddef>
struct A {
    static constexpr int (*off_p)(int p) =
        [](int off = offsetof(A, a))  { return off; };
    int t[off_p(1)];
    char a;
};
```

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
                   ` (4 preceding siblings ...)
  2023-10-22 23:08 ` pinskia at gcc dot gnu.org
@ 2023-10-22 23:27 ` stsp at users dot sourceforge.net
  2023-10-23  8:05 ` stsp at users dot sourceforge.net
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: stsp at users dot sourceforge.net @ 2023-10-22 23:27 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

--- Comment #6 from Stas Sergeev <stsp at users dot sourceforge.net> ---
(In reply to Andrew Pinski from comment #5)
> Nope, lamdba's are not a nested class.

But according to this:
https://timsong-cpp.github.io/cppwp/n3337/expr.prim.lambda#3
The type of the lambda-expression (which is also the type of the closure
object) is a unique, unnamed non-union class type — called the closure type —
whose properties are described below. This class type is not an aggregate
([dcl.init.aggr]). The closure type is declared in the smallest block scope,
class scope, or namespace scope that contains the corresponding
lambda-expression.

So am I right that defining lambda
in class A, means defining it in a
class's scope? In which case note4
should apply? What am I missing?

Additionally I've got this to compile:

struct A {
    struct dummy {
        static constexpr int foo(int off = offsetof(A, a)) { return off; }
        static constexpr int operator()() { return foo(); }
    };
    static constexpr int (*off_p)() = &dummy::operator();

    int x;
    char a;
};

Seems like note4 applies in that case.
But it should be very similar to the
"closure type" described above...

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
                   ` (5 preceding siblings ...)
  2023-10-22 23:27 ` stsp at users dot sourceforge.net
@ 2023-10-23  8:05 ` stsp at users dot sourceforge.net
  2023-10-24 10:25 ` stsp at users dot sourceforge.net
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: stsp at users dot sourceforge.net @ 2023-10-23  8:05 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

--- Comment #7 from Stas Sergeev <stsp at users dot sourceforge.net> ---
Also I verified your assumption in
comment #5 by this code:

struct A {
    struct dummy {
        static constexpr const int foo(const int off = offsetof(A, a)) { return
off; }
        static constexpr const int operator()() { return foo(); }
    };
    static constexpr const int (*off_p)() = &dummy::operator();

    int t[off_p()];
    char a;
};

It says:

error: size of array ‘t’ is not an integral constant-expression
   11 |     int t[off_p()];

So it seems, "constexpr const" is not
enough to alter the structure size, so
your fears about that were likely wrong.

So could you please explain why note4 doesn't
apply to the nested closure type? Unless
there is a consistent explanation, the
chances are that the bug is missed. :(

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
                   ` (6 preceding siblings ...)
  2023-10-23  8:05 ` stsp at users dot sourceforge.net
@ 2023-10-24 10:25 ` stsp at users dot sourceforge.net
  2023-10-24 23:16 ` richard-gccbugzilla at metafoo dot co.uk
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: stsp at users dot sourceforge.net @ 2023-10-24 10:25 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

--- Comment #8 from Stas Sergeev <stsp at users dot sourceforge.net> ---
Added a few experts who can probably
answer that. While I do not doubt that
Andrew is right, I am sure having the
properly spelled explanation will help.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
                   ` (7 preceding siblings ...)
  2023-10-24 10:25 ` stsp at users dot sourceforge.net
@ 2023-10-24 23:16 ` richard-gccbugzilla at metafoo dot co.uk
  2023-10-24 23:30 ` stsp at users dot sourceforge.net
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: richard-gccbugzilla at metafoo dot co.uk @ 2023-10-24 23:16 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

--- Comment #9 from Richard Smith <richard-gccbugzilla at metafoo dot co.uk> ---
I don't think we intended for default arguments of class-scope lambdas to get
the same complete-class context treatment as default argument of member
functions, but the standard wording does currently seem to suggest that they do
get that treatment.

Filed https://github.com/cplusplus/CWG/issues/449 to suggest the standard
wording be fixed to match the implementations.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
                   ` (8 preceding siblings ...)
  2023-10-24 23:16 ` richard-gccbugzilla at metafoo dot co.uk
@ 2023-10-24 23:30 ` stsp at users dot sourceforge.net
  2023-10-25  1:35 ` stsp at users dot sourceforge.net
  2024-02-03 20:08 ` jens.maurer at gmx dot net
  11 siblings, 0 replies; 13+ messages in thread
From: stsp at users dot sourceforge.net @ 2023-10-24 23:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

--- Comment #10 from Stas Sergeev <stsp at users dot sourceforge.net> ---
OMG, not what I intended to get. :(
All I need is to use offsetof() in templates.
Last time I started to use reinterpret_cast
for that, you disallowed reinterpret_cast in
constexpr context. Now this...
Why is it such a big deal to disallow every
possible loop-hole for the use of offsetof()
in templates?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
                   ` (9 preceding siblings ...)
  2023-10-24 23:30 ` stsp at users dot sourceforge.net
@ 2023-10-25  1:35 ` stsp at users dot sourceforge.net
  2024-02-03 20:08 ` jens.maurer at gmx dot net
  11 siblings, 0 replies; 13+ messages in thread
From: stsp at users dot sourceforge.net @ 2023-10-25  1:35 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

--- Comment #11 from Stas Sergeev <stsp at users dot sourceforge.net> ---
So if I understand correctly, before
your proposal the following code was
conforming:

template <auto O>
struct B {
    static constexpr int off = O();
};

struct A {
    char a;
    B<[]() static constexpr ->int { return offsetof(A, b); }> b;
};

due to 7.1 (function body) + note4 for
closure sub-class.
Do you know any specific reason why that
code should be disallowed, rather than
supported per the current standard?
After reinterpret_cast is constexpr was
also disallowed, it became quite challenging
to come up with the work-around.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/111923] default argument is not treated as a complete-class context of a class
  2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
                   ` (10 preceding siblings ...)
  2023-10-25  1:35 ` stsp at users dot sourceforge.net
@ 2024-02-03 20:08 ` jens.maurer at gmx dot net
  11 siblings, 0 replies; 13+ messages in thread
From: jens.maurer at gmx dot net @ 2024-02-03 20:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111923

Jens Maurer <jens.maurer at gmx dot net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jens.maurer at gmx dot net

--- Comment #12 from Jens Maurer <jens.maurer at gmx dot net> ---
In general, we want to be rather careful that the layout of the non-static data
members of a class cannot depend on properties of other non-static data members
that are visible due to some "complete class" rules.

Otherwise, it's way too easy to construct cycles.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2024-02-03 20:08 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-22 22:42 [Bug c++/111923] New: default argument is not treated as a complete-class context of a class stsp at users dot sourceforge.net
2023-10-22 22:51 ` [Bug c++/111923] " pinskia at gcc dot gnu.org
2023-10-22 22:56 ` pinskia at gcc dot gnu.org
2023-10-22 22:58 ` pinskia at gcc dot gnu.org
2023-10-22 23:04 ` stsp at users dot sourceforge.net
2023-10-22 23:08 ` pinskia at gcc dot gnu.org
2023-10-22 23:27 ` stsp at users dot sourceforge.net
2023-10-23  8:05 ` stsp at users dot sourceforge.net
2023-10-24 10:25 ` stsp at users dot sourceforge.net
2023-10-24 23:16 ` richard-gccbugzilla at metafoo dot co.uk
2023-10-24 23:30 ` stsp at users dot sourceforge.net
2023-10-25  1:35 ` stsp at users dot sourceforge.net
2024-02-03 20:08 ` jens.maurer at gmx dot net

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).