Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
To: ffmpeg-devel@ffmpeg.org
Subject: Re: [FFmpeg-devel] [PATCH] lavfi: get rid of FF_INTERNAL_FIELDS
Date: Sat, 4 Feb 2023 16:27:31 +0100
Message-ID: <AS8P250MB0744479F3C4C72504341FF758FD49@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <Y90eEgTfOCLQGVi2@phare.normalesup.org>

Nicolas George:
> Andreas Rheinhardt (12023-02-01):
>> "One special guarantee is made in order to simplify the use of unions:
>> if a union contains several structures that share a common initial
>> sequence (see below), and if the union object currently contains one of
>> these structures, it is permitted to inspect the common initial part of
>> any of them anywhere that a declaration of the completed type of the
>> union is visible. Two structures share a common initial sequence if
>> corresponding members have compatible types (and, for bit-fields, the
>> same widths) for a sequence of one or more initial members."
>>
>> But there just is no union between the FF_INTERNAL_FIELDS
>> !defined(FF_INTERNAL_FIELDS) structures in the whole codebase.
> 
> It is not necessary that there is one: it is enough that there could be
> one in another compilation unit, the code that handles these structures
> does not know what exists in the rest of the code base. This guarantee
> was made FOR unions, but it does not REQUIRE unions, it applies to
> anything that is semantically equivalent to a union.
> 

1. The common initial sequence rule indeed forced traditional compilers
to use the same offsets for the members of the common initial sequence
of two arbitrary structs, because there might be a union of these two in
another translation unit. But this is no longer true for lto compilers
that see the whole program at once (although I don't think that they
will deviate from the behaviour of traditional compilers in this regard).
2. But even if the offsets are fine, does not mean that the accesses are
fine. Notice the clause "anywhere that a declaration of the completed
type of the union is visible" above? It is accompanied with the
following example:

"The following is not a valid fragment (because the union type is not
visible within function f):
struct t1 { int m; };
struct t2 { int m; };
int f(struct t1 *p1, struct t2 *p2)
{
    if (p1->m < 0)
        p2->m = -p2->m;
    return p1->m;
}
int g()
{
    union {
        struct t1 s1;
        struct t2 s2;
    } u;
    /* ... */
    return f(&u.s1, &u.s2);
}"


>> Furthermore, said guarantee is only for inspecting, i.e. reading. For
>> example, for the following two structs sharing a common initial sequence,
>>
>> struct Small {
>>     uint64_t foo;
>>     uint32_t bar;
>> };
>> struct Big {
>>     uint64_t foo;
>>     uint32_t bar;
>>     uint32_t baz;
>> };
>>
>> if one had a union { struct Small; struct Big; }, a write to Small.bar
>> may clobber Big.baz.
> 
> That is a good point. It does not apply when the first field of Big is
> Small itself, which is the case that I absolutely know is supported,
> because in that case Big will embed the padding of Small. I had not
> thought of this.
> 
> Fortunately, even if we are not 100% in the case that is officially
> supported, there are multiple reasons that each should be enough to
> guarantee that our code will work:
> 

I'd rather have something that is actually supported and spec-compliant.
Anyway, I worry more about lto-compilers than about traditional
compilers accidentally clobbering something (after all, most of our
fields are sizeof(int)-sized or a multiple (double) thereof, so CPU
instruction sets can write this natively and there is no advantage in
touching padding).

> - Between the public part of the structure and the #ifede
>   FF_INTERNAL_FIELDS, there are a lot of "not part of the public API"
>   fields", changing ch_layout will not clobber incfg because incfg is
>   known at this point.
> 
> - Even if there was no fields in between, reserved[] offers the same
>   protection.
> 
> - And even if there was no gap, we are good because applications, and
>   even filters, are not supposed to modify AVFilterLink, only the
>   framework and the framework knows the whole structure.
> 
> In fact, that last remark makes me think of another solution, for the
> slightly longer term: make AVFilterLink entirely opaque. The only
> documented reason for application to access AVFilterLink was to get the
> parameters of buffersink, but buffersink has a real API to get this
> since 2016.
> 
> Anyway, if you prefer using a compilation option, I have no objection.
> My only concern is that when a developer writes:
> 
> 	if (link->x == ... &&
> 	    link->y == ... &&
> 	    link->status_in == ... &&
> 	    link->min_samples == ..)
> 
> they have to remember that no, status_in is different from all the
> others.
> 
> And it is especially bad in this particular case because the distinction
> is not public / private, which makes some semantic sense and might be
> easier to remember, the distinction is actually
> public-or-private-because-of-a-comment / private-because-of-a-ifdef.
> 
> But even if the distinction really was public / private, I consider it
> unacceptable if we can do otherwise. And we can.
> 
> Regards,
> 

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

      parent reply	other threads:[~2023-02-04 15:27 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-30 12:29 Anton Khirnov
2023-01-30 12:32 ` Paul B Mahol
2023-01-30 12:40 ` Nicolas George
2023-01-31 13:50   ` Anton Khirnov
2023-01-31 14:03     ` Nicolas George
2023-01-31 14:14       ` Paul B Mahol
2023-01-31 14:32         ` Nicolas George
2023-01-31 14:50           ` Paul B Mahol
2023-01-31 14:18       ` Anton Khirnov
2023-01-31 14:31         ` Nicolas George
2023-01-31 15:24           ` Anton Khirnov
2023-01-31 16:13             ` Nicolas George
2023-01-31 16:34               ` Nicolas George
2023-01-31 21:02                 ` Andreas Rheinhardt
2023-01-31 21:16                   ` Nicolas George
2023-02-01  0:31                     ` Andreas Rheinhardt
2023-02-01  7:47                       ` Nicolas George
2023-02-01 13:48                         ` Andreas Rheinhardt
2023-02-03 14:45                           ` Nicolas George
2023-02-04 11:09                             ` Uoti Urpala
2023-02-04 15:27                             ` Andreas Rheinhardt [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AS8P250MB0744479F3C4C72504341FF758FD49@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM \
    --to=andreas.rheinhardt@outlook.com \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git