C++ Logo


Advanced search

Re: [wg14/wg21 liaison] UB

From: Hans Boehm <boehm_at_[hidden]>
Date: Fri, 26 May 2023 13:50:57 -0700
On Fri, May 26, 2023 at 1:10 PM Jₑₙₛ Gustedt <jens.gustedt_at_[hidden]> wrote:

> Hans,
> on Fri, 26 May 2023 09:06:15 -0700 you (Hans Boehm <boehm_at_[hidden]>)
> wrote:
> > There are currently also a few more not-obviously-localized forms of
> > undefined behavior, even in the C standard. In N3096, I found
> >
> > footnote 92 (header names)
> >
> > restrict seems tricky, buit can probably be handled like data races?
> >
> > "The execution of a non-directive preprocessing directive results in
> > undefined behavior."
> Yes there is a completely different source of undefined behavior that
> is actually not related to faults in the execution but is merely there
> to leave slackness to the implementors.
> > Referring to signal(): "Use of this function in a multi-threaded
> > program results in undefined behavior." Actually, I don't understand
> > why that's there at all. I could see "implementation defined".
> Implementation-defined behavior is different from undefined behavior
> and unspecified behavior, in that it requires that the behavior is
> documented. So here we do not even demand that they document what they
> are doing.
> > As it stands, if I call signal(), and then create threads, it
> > encounters undefined behavior at the first thread creation?
> This is a most pessimistic interpretation ;-)
> More directly from the text follows that calling that `signal` in an
> execution that has (had) multiple threads, is a fault. This was what
> I was first thinking, too, but it may be more subtle than that,
> actually. It is undefined what concerns the C standard, but it also
> means that other standards such as POSIX may prescribe some specific
> behavior here.
Posix doesn't have that restriction, though I think its wording is otherwise
a bit obsolete.

I read the wording here as also prohibiting signal() if we later fork a
thread, with the motivation of dodging issues about where the handler runs.
That would mean that "safe" visible side-effects would need to happen
before the later of the signal() call and the initial thread creation.

It would be good to clarify what was actually intended.

> > Do we guarantee that the standard library doesn't create threads
> > behind the scenes?
> I think that the intent for an "as-if" property is there, but this is
> kind of hidden. A C library implementation could under some
> circumstances create multiple threads for `qsort`, for example, as
> long as all the additional threads are well synchronized, they
> guarantee that no signal is raised, and all additional threads are
> gone when `qsort` returns.
That makes sense. (I'm not sure qsort is the best example here.
That parallelization is only correct if you can somehow determine that
the comparator function is thread-safe, in a very strong sense.)


> Jₑₙₛ
> --
> :: ICube :::::::::::::::::::::::::::::: deputy director ::
> :: Université de Strasbourg :::::::::::::::::::::: ICPS ::
> :: INRIA Nancy Grand Est :::::::::::::::::::::::: Camus ::
> :: :::::::::::::::::::::::::::::::::::: ☎ +33 368854536 ::
> :: https://icube-icps.unistra.fr/index.php/Jens_Gustedt ::

Received on 2023-05-26 20:51:09