C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] On _Thread_local for better C++ interoperability with C (P2478)

From: Corentin <corentin.jabot_at_[hidden]>
Date: Sat, 12 Feb 2022 11:48:22 +0100
On Sat, Feb 12, 2022 at 11:26 AM Jₑₙₛ Gustedt <jens.gustedt_at_[hidden]> wrote:

> Corentin,
> I am not sure that I get your example correctly.
>
> on Sat, 12 Feb 2022 11:09:26 +0100 you (Corentin via Liaison
> <liaison_at_[hidden]>) wrote:
>
> > My understanding of the issue was as follows:
> > There is a thread_local which is a C++ type (thereby not extern) ,
> > passed to a C function, from within a C++ function.
> > Such thread_local could be declared at function scope.
> >
> > struct S {
> > S();
> > };
>
> This type can never be properly used as such by a C function, can't it?
>
> So what a C TU should see at most is a `struct S` forward
> declaration. Showing C a `struct` definition that lies about the fact
> that this has a constructor is an error.
>

I would very like to see a clear statement of the actual problem with code
examples because I'm *very* confused
(which might very well be because I do not have a functional brain, so
please bear with me)

C structs, by definition, are trivial types from a C++ perspective and so a
C++ compiler will not generate
constructor calls for them, or destructor calls for that matter, on the
ground there is nothing to construct or destroy.

My understanding of the original problem statement is that

* There is a non trivial thread local object
* That is accessed *somehow* (and I agree with you that I don't see how
exactly) by C
* At that point, because C++ compiler defer initialization to reads, the
thread_local c++ variable may not be initialize
* C observes a non-initialized variable

Is that, or is it not, the scenario of concern here?
In particular:


   - do we agree thread_local of trivial types behave the same in either
   language?
   - do we agree thread_local of trivial types could/should behave the same
   in either language?
   - do we think passing C++ type to C functions to be a valid use case?
   - what is the semantic we are thinking of for extern "C" thread_local ?
      - eagerly initialize
      - make it ill-formed to declare non-trivial extern "C" thread_local
      objects, such that extern "C" thread_local would be equivalent to
      static_assert(std::is_trivial_v<Type>)




> > extern "C" {
> > void foo(S*);
> > static thread_local S s; // would be okay, with different semantics
> > (eager initialization)
> > };
> >
> >
> > void f() {
> > /* extern "C" */ static thread_local S s; // Do we care to support
> > that ? foo(&s);
> > }
>
> This function can't be written in C, because C wouldn't know about
> the constructor.
>
> > Here I don't think users will necessarily want to put f in the extern
> > "C" scope, for example.
> > The variable needs to be in an extern "C" scope, not necessarily the
> > enclosing function
>
> You'd have to have C linkage for `f` if you'd want to call it from C,
> but the implementation of `f` should always be made in C++, because
> `struct S` is a type that C can't handle.
>
> Jₑₙₛ
>
> --
> :: INRIA Nancy Grand Est ::: Camus ::::::: ICube/ICPS :::
> :: ::::::::::::::: office Strasbourg : +33 368854536 ::
> :: :::::::::::::::::::::: gsm France : +33 651400183 ::
> :: ::::::::::::::: gsm international : +49 15737185122 ::
> :: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::
>

Received on 2022-02-12 10:48:34