Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[module.private.frag] A confused example #4890

Open
xmh0511 opened this issue Sep 10, 2021 · 4 comments
Open

[module.private.frag] A confused example #4890

xmh0511 opened this issue Sep 10, 2021 · 4 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Sep 10, 2021

export module A;
// #1
export inline void fn_e();      // error: exported inline function fn_­e not defined
                                // before private module fragment
// #2
inline void fn_m();             //  OK, module-linkage inline function
static void fn_s();
export struct X;
export void g(X *x) {
  fn_s();                       // OK, call to static function in same translation unit
  fn_m();                       // OK, call to module-linkage inline function
}
export X *factory();            // OK

module :private;
struct X {};                    // definition not reachable from importers of A
X *factory() {
  return new X ();
}
void fn_e() {}
void fn_m() {}
void fn_s() {}

In this example, #1 and #2 both attach to module A, they have external or module linkage, respectively. In terms of this case, [basic.def.odr] p11, [dcl.inline] p5 and p7 should apply to both #1 and #2. The definition of definition domain is defined as that

A definition domain is a private-module-fragment or the portion of a translation unit excluding its private-module-fragment (if any).

I'm not sure whether the intent of this rule is that a private-module-fragment can divide out another definition domain in a translation unit. If it is, #2 should be ill-formed since it is odr-used in the first definition domain but its definition appears in another domain, as per [basic.def.odr] p11

A definition of an inline function or variable shall be reachable from the end of every definition domain in which it is odr-used outside of a discarded statement.

Except that, I'm not seeing any difference between #1 and #2 in terms of this example, that is, they should have the same treatment unless there are some normative rules that differentiate them in this case.

@xmh0511 xmh0511 changed the title [module.private.frag] A confusion example [module.private.frag] A confused example Sep 10, 2021
@jensmaurer
Copy link
Member

In your example, there are two definition domains: One is the private-module-fragment; the other one is the rest of the translation unit.
[basic.def.odr] p11 says that the definition of fn_m needs to be reachable from "the rest", but it isn't. I'd say the use inside g is thus ill-formed. If your compiler says otherwise, maybe you should consider posting a bug report to your vendor?

My guess is that at #1, the compiler just wants to be helpful and tell you that you can never odr-use that exported function, because the definition cannot ever be reachable.

@xmh0511
Copy link
Contributor Author

xmh0511 commented Sep 10, 2021

This example is a formal case located in [module.private.frag], I just think the comments are confusing here. We agree on fn_m, which should be ill-formed. For fn_e, violates [dcl.inline] p7 may the reason why it is an error.

If an inline function or variable that is attached to a named module is declared in a definition domain, it shall be defined in that domain.

The definition is defined in private-module-fragment but not in the rest.

@opensdh
Copy link
Contributor

opensdh commented Sep 20, 2021

P1815R2 probably outdated the example; it certainly outdated the one in [module.interface]/7 that says

namespace {
  struct S { };
}
export void f(S);  // OK

@xmh0511
Copy link
Contributor Author

xmh0511 commented Sep 22, 2021

Agree! it should be ill-formed since it violates [basic.link] p17.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants