C++ Logo


Advanced search

Re: [SG14] No call tomorrow Aug 11

From: Patrice Roy <patricer_at_[hidden]>
Date: Tue, 7 Sep 2021 19:20:39 -0400
Thanks; I'll read it soon and process it. Note that the document's contents
come from users, and I'm sure we'll take some, integrate some into existing
efforts, adjust some, etc. but I'm glad the idea seems interesting to you.

Looking forward to tomorrow!

Le mar. 7 sept. 2021 à 13:43, Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]> a
écrit :

> Some quick comments on the doc:
> (1) Nice work!
> (2) s/invalid_refererencing/invalid_dereferencing/. A better name for this
> attribute would be [[frees]] or [[deletes]], since the intent (at least in
> realloc's case) is that it takes ownership of the resource. `void
> free([[frees]] void *p)` should be annotated in the same way. However, this
> attribute is fairly useless in C++, because (A) we have so many different
> kinds of resources, and (B) we have RAII for this. If you're able to change
> your code to add a [[frees]] attribute, you're (in theory) also able to
> change it to make it take unique_ptr instead. unique_ptr's calling
> convention is worse than the raw-pointer calling convention, but that's an
> orthogonal topic, and we already have a non-standard attribute for that
> (apply [[trivial_abi]] to your codebase's unique_ptr class).
> (3) Overloading based on constexpr arguments: Your example here reminds me
> of
> https://quuxplusone.github.io/blog/2021/08/07/p2266-field-test-results/#libreoffice-ostring
> and it has the same issue:
> struct MyString { MyString(constexpr const char *p) { assume the
> string's contents will never change } };
> char buf[10] = "hello";
> constexpr const char *p = buf;
> int main() {
> MyString m = p; // initializing m with a compile-time-constant
> pointer to some const chars
> strcpy(buf, "goodbye");
> std::cout << m; // oops, the string's contents have changed
> }
> C++ does not give the programmer any tools to detect whether something is
> a string literal or not. There have been past proposals for something like
> `std::string_literal`, a magic library type similar to
> std::initializer_list<T>, so that functions could opt into taking only
> string literals instead of arbitrary arrays-of-char. Of course some people
> would want the string's value to be compile-time-manipulable, and others
> would want it to be "erased" (non-compile-time) in the same way as
> std::initializer_list<T> in order to avoid template bloat, and actually a
> lot of people (N4121, P1378; P0259 is related) seem to want the *length*
> of the literal to be compile-time-available but the *character values* to
> be "erased."
> (4) The printed discussion around std::variable_name() makes it pretty
> clear to me that they really just want std::source_location()... and in
> C++20 they have that. The parenthetical "note: more than what is provided
> by source_location" seems wrong, since source_location *does* provide a
> `line` member. That bullet point should be removed, or fleshed out.
> (5) Compile-time string interpolation: '$' is controversial, but 'f' is
> standard Python, so I recommend just switching your examples to use
> f"strings" instead. Then you can eliminate the distracting digression.
> (6) s/is_complete_type_type/is_complete_type/. Also, this is a really
> really bad idea, for deep core-language reasons. See
> https://stackoverflow.com/questions/1625105/how-to-write-is-complete-template
> https://reviews.llvm.org/D108645
> https://godbolt.org/z/nr3dPY7va
> However, also notice that the OP's problem (failing to print a nice
> static_assert message) is solved in C++20 because you can write ad-hoc
> well-formedness constraints:
> static_assert(requires{ sizeof(T); }, "type incomplete, or maybe not
> an object type");
> static_assert(sizeof(T) >= 4, "type too small");
> Also, having an is_complete<T> trait wouldn't solve OP's problem, because
> what are you going to do?
> static_assert(is_complete_v<T> && sizeof(T) >= 4, "type too small");
> would still fail to print the nice message; splitting it into two
> static_asserts just gets back a lesser version of the C++20 solution.
> Lesser because e.g. [T=int()] is a type where sizeof(T) doesn't compile,
> and yet T is a complete type. If you're trying to check that sizeof(T) is
> well-formed, *just check that*; don't mess around with abstract ideas
> like "completeness" that don't fully capture the sense of what you need.
> (7) SOO thresholds: I recommend changing your strawman syntax to
> std::function<void()>::max_soo_size(). There's no reason to use a
> type-trait here, because (A) this isn't a place for generic dispatch and
> (B) this isn't a place for user customization. The right precedent is
> something like unordered_map.bucket_count(): an idiosyncratic
> implementation detail that we're exposing on the bad assumption that
> someone cares about it.
> Why "bad assumption"? Because SOO is conditioned on *more than just size*.
> https://quuxplusone.github.io/blog/2019/03/27/design-space-for-std-function/#sbo-affects-semantics
> - Some vendors' std::function will store small objects on the heap anyway,
> unless they are nothrow_move_constructible.
> - Some vendors' std::function will store small objects on the heap anyway,
> unless they are trivially_move_constructible and trivially_destructible.
> So, just knowing that your lambda-or-whatever *is physically small enough
> to fit* doesn't tell you that the vendor actually *will* use SOO. So, if
> you pursue this at all, maybe the right interface would be a sort of "dry
> run constructor," here spelled `will_hold_inline`:
> using F = std::function<void()>;
> auto t = []() { puts("whatever lambda"); };
> if (F::will_hold_inline(t)) {
> F f = t;
> assert(f.is_held_inline());
> } else {
> F f = t;
> assert(!f.is_held_inline());
> }
> (8) Re inplace_function "implementation experience": You might link to the
> SG14 repo's implementation. ;) And I'd be interested to learn whether any
> of your contributors are actually using it in practice, and if not, why
> not, and how can we get them to switch to it. I mean, if people are
> avoiding an existing free library and rolling their own anyway, then how
> can we be sure that they wouldn't have the same reaction to a
> std::inplace_function after standardization? In which case, standardizing
> inplace_function would be wasted effort.
> (9) SOO-Enabled Vector: Differentiate between `fixed_capacity_vector<T,
> Cap>` (Boost's static_vector, P0843, fixed capacity, "fails" when the
> capacity is exceeded — and defining the behavior on "failure" is ugly) and
> `small_vector<T, SOOCap=SomeDefault>` (LLVM's SmallString IIRC, infinite
> capacity, heap-allocates when the SOO is exceeded).
> (10) External Buffer Vector: Is this basically a way of "transferring
> ownership" of an allocation from the user into `vector`, and/or
> transferring ownership back out? Having a general-purpose interface for
> transferring allocations would in general be pretty great... but would also
> be a nightmare to specify, and would really lock down vendors into one
> specific implementation (which might not be bad).
> std::vector<char> v = {'a', 'b', 'c', 'd'};
> struct TakeResult { char *ptr; size_t len; size_t cap; }; // and also
> a copy of the relevant allocator?
> TakeResult tr = v.take(); // take ownership of the allocation
> assert(v.empty());
> std::string s;
> s.adopt(std::move(tr)); // transfer ownership of the allocation to a
> string!
> // actually, uh-oh, s needs to become null-terminated somehow
> Or is this more like a std::pmr::vector attached to a
> monotonic_buffer_resource (which uses a fixed buffer first, if provided;
> and then switches to heap allocation)?
> (11) s/heap-free/non-allocating/, if I understand correctly. I was
> initially confused that maybe a "heap-free function" was the opposite of a
> "heap-malloc function."
> (12) "No-RTTI" Guarantees: Yes, `std::pmr::memory_resource::do_is_equal`
> used to specifically mandate the use of dynamic_cast, but LWG3000 fixed
> that.
> https://cplusplus.github.io/LWG/issue3000
> Unfortunately, I notice that there's still a non-normative note on the
> pure virtual method that encourages use of dynamic_cast in derived user
> types. Maybe someone should open an LWG issue to eliminate that note.
> https://eel.is/c++draft/mem.res.class#mem.res.private-note-1
> (13) Predictable lambdas: Perhaps like this (C++17):
> auto make_lambda(std::string s) { return [s](auto t) { return s + t +
> "!"; }; }
> int main() {
> using LambdaType = decltype(make_lambda(""));
> alignas(LambdaType) char buffer[sizeof(LambdaType)];
> auto *lam = ::new ((void*)buffer) LambdaType( make_lambda("hello
> ") );
> (*lam)("world");
> lam->~LambdaType();
> }
> or like this (C++20) for captureless lambdas only:
> int main() {
> using LambdaType = decltype([](int x) { return x + 1; });
> alignas(LambdaType) char buffer[sizeof(LambdaType)];
> auto *lam = ::new ((void*)buffer) LambdaType();
> (*lam)(42);
> lam->~LambdaType();
> }
> (14) s/Suport/Support/
> (15) Your [[invalidate_dereferencing]] and [[invalidate]] attributes are
> the same thing: they both say "this pointer gets freed."
> (16) [[no_copy]]: I agree with you, this is just "Delete your copy
> constructor."
> (17) [[rvo]]: The example is solved by "Delete your copy and move
> assignment operators." Since C++17, we've had the new prvalue rules that
> make "copy elision" quite predictable, so it's also easy to work with
> non-movable types like std::lock_guard.
> However, it sounds like the text doesn't match the example. The text is
> talking about annotating a single function's *definition* (not its
> declaration/uses) and forcing the compiler to complain if the RVO is not
> used. Besides P2025, there's relevant prior art in Clang's non-standard
> [[musttail]] attribute:
> https://reviews.llvm.org/D99517
> where you annotate a specific return statement and say, "This return
> statement must get optimization X; otherwise, error."
> (18) [[side_effect_free]], a.k.a. [[pure]], a.k.a. [[const]]... the
> problem here is that there are so many things "pure" might mean in C++.
> This is related to my point number (3), where we have a constexpr pointer
> to const chars and yet those chars' values can change at runtime. Same
> thing here. You might think `strlen` is a pure function, but in fact
> char g[] = "hello world";
> void f() { g[5] = '\0'; }
> int main() {
> const char *p = g;
> strlen(p); // returns 11
> f();
> strlen(p); // returns 5
> }
> So you have to start by figuring out what property the average programmer
> actually cares about, and then work on nailing down exactly how to specify
> that property. Specifying a "similar but less useful" property is... less
> useful. And in practice it turns out that the average programmer doesn't
> care about any of these properties, because calling strlen twice is plenty
> fast; and if calling strlen twice ever does end up being too slow, they'll
> just call it once and cache the value in a local variable. ;) Giving the
> compiler enough information to figure out that optimization on its own has
> a high cost (in terms of human brain cells to make sure you got it right)
> and a low benefit.
> I'll add that any annotation that depends on human input like this *will*
> be misused. Remember my [[trivially_relocatable]] talk? Facebook had been
> enabling their trivially-relocatable trait for `std::list`, but `std::list`
> was not in fact trivially relocatable! This led to segfaults when resizing
> a vector<list<int>>. If you rely on the programmer to decide whether their
> function ComputeSomeExpensiveOperation() is [[pure]] or not (based on some
> standardese definition of purity that nobody at the company has ever read,
> let alone understood), they *will* mark too much stuff as [[pure]], and
> eventually it will bite them.
> (19) Move Semantics, page 14: IMHO a typoed "copy constructor" with
> signature `T(const T&&)` should be caught by clang-tidy or grep, not by any
> C++2b core-language change.
> (20) "99% of the code to be slower" — IMO this is repeating a common
> misconception. The executable will be *bigger* due to stack-unwinding
> tables, but those tables go in .rodata, not .text; that shouldn't
> noticeably affect the *speed* of the non-throwing code. There's no "ooh,
> this next bit might throw, so set up some handlers in preparation." That
> just isn't how EH works anymore. It's all static precomputed tables, kept
> off to the side: "oops, this line seems to have thrown; let me consult my
> data tables and see what I'm supposed to do now."
> You can't modify the person's quote, of course, but I think you should do
> something to indicate that it's "perception not reality."
> (21) s/amout/amount/
> (22) A direct URL to some tutorial material on "nameof" would be very
> helpful. I have not googled it yet myself.
> (23) "help catch more errors at compile time" — Obviously yes. But this is
> not useful feedback to the Committee. This sentence implies that game devs
> have a workflow where it's, like, "oh no, the game crashed at runtime...
> let's find the bug... okay, found it, we accidentally _______; gee, I wish
> the compiler had told us about that at compile time!" The only missing
> piece is, *what goes in the blank?* What are they doing over and over
> that they wish the compiler would catch? Without telling us that, we can't
> really do anything to help, at compile time or otherwise.
> (24) Conditional Compilation: Given that you already have `#ifdef`, what's
> the motivation for a new conditional-compilation facility? Why does it
> need replacing?
> (25) The feedback on "ASIO or not to ASIO?" seems less opinionated than
> I'd wish for. It sounds like the contributors don't realize that (AFAIK) *Networking
> will be ASIO by default*, and so it's not terribly useful to say "well, I
> don't need all of ASIO... really I just need some standard BSD-sockets
> stuff... I don't ask for much... never mind me..." :) because if you let
> the Networking group just do their own thing, I'm pretty sure you're *not
> going to get* any BSD-sockets stuff. It's all going to be io_contexts and
> executors and crap. (In particular, you seem to be conflating "the
> low-level std:: API for networking" with "the thing gamedevs will actually
> build on top of." What if the low-level std:: API is ASIO, and gamedevs
> don't want to build on top of ASIO? Would they continue to ignore it and
> build their own stuff next to it?) If you *positively want* sockets,
> speak louder. And if you positively want ASIO, also speak louder. And if
> different contributors want both, say that. And if nobody cares, say that.
> But it's hard to tell what position you're taking at the moment.
> (26) "We need a way to name a standard thread ... unpleasant" — Honestly,
> I've worked on at least two codebases that named their threads, and it was
> not unpleasant at all. It was like, you write *one* ten-line function
> `void set_current_thread_name(const std::string& name)` — or honestly, copy
> it from the last time you had to write it — and then you never look at that
> code again. It is the exact opposite of unpleasant. Yes, of the function's
> ten lines, about five are #ifdefs; but that's not a problem at all. Write
> once, never look at it again.
> (27) Stack size is fundamentally different from name and priority and
> affinity, because you cannot change it on an existing thread; it needs to
> be a parameter to std::thread's constructor (or something like that). Name,
> etc., can all be set from within the thread after it's started running. You
> should reflect that difference in your discussion.
> (28) "some metadata from a mutex" — This is basically Clang's
> thread-safety attributes?
> https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
> I've never used them nor have any special knowledge of them, but it sounds
> like what you want. It would be good to know whether any contributors have
> used them, whether they suffice or are lacking in some way (besides "not
> being standard yet"), etc.
> (29) Logging — Notice that adding logging to a function probably renders
> it non-[[pure]]. See (18). ;)
> (30) Forward Class Declarations: As long as each base class is a complete
> type, I think this can be implemented. If you allow incomplete base
> classes, then it can't be done (or at least the results are not useful to
> the programmer).
> struct E {};
> struct A;
> struct B : E, A {};
> B *b = f();
> A *a = b; // this cannot be compiled because we don't know the offset
> of B's A subobject: it depends on whether A derives from E or not
> There's also a syntactic problem: You can't express "I forward-declare
> that this class type exists and has *no base classes.*" This is analogous
> to the problem C89 had in distinguishing between `int f();` and `int
> f(void);`: we've already gobbled up the obvious syntax and made it mean
> "this exists *and I'm not saying anything about* its base classes."
> (31) Constrained Construction: Wat. In what way is this useful?
> particularly to gamedevs/embedded?
> (32) Better Support of Arrays...: This is a (good) argument why not to use
> `std::byte` for anything ever. For normal strong enums, though, where they
> have named enumerators instead of being some sort of half-assed fundamental
> type, this is not a problem at all.
> enum class Color = { RED, GREEN, BLUE };
> Color array[] = { Color::GREEN, Color::RED }; // OK, and looks fine
> using enum Color; Color array[] = { GREEN, RED }; // OK in C++20, I
> think
> If you really want to use std::byte with literal values, consider using a
> macro or a custom UDL:
> #define B(x) std::byte(x)
> auto operator""_b(int v) { return std::byte(v); }
> std::byte array[] = { B(0), B(1), B(42), B(0); };
> std::byte array[] = { 0_b, 1_b, 42_b, 0_b };
> But personally I strongly recommend `unsigned char` instead. I'd like to
> know why the contributors feel `unsigned char` is insufficient for their
> needs.
> (33) "Cannot add MyString(std::initializer_list) anymore" — Missing
> `<char>`. But also, I think the example is wrong. An initializer_list
> overload can coexist there just fine; std::vector<char> gets away with it.
> The problem would happen if the element type itself were `int`:
> MyString(int chr, int count); // #1, pre-existing
> MyString(std::initializer_list<int>); // #2, trying to add this one
> ...
> MyString indent{32, 4}; // used to call #1, now calls #2
> Personally I strongly recommend
> https://quuxplusone.github.io/blog/2019/02/18/knightmare-of-initialization/#simple-guidelines-for-variable-i
> specifically, never using curly braces *unless* you mean
> initializer-list-initialization, which eliminates this problem completely.
> But I admit that in a large existing codebase with a lot of people working
> on it (and high turnover), *enforcing* this common-sense rule is not easy.
> (34) Downcasting — Needs an example. I believe I understand the intent;
> it's talking about this, right?
> template<class MDT, class Base> MDT *downcast(Base *p) { return
> static_cast<MDT*>((typeid(*p) == typeid(MDT)) ? p : nullptr); }
> As with (26), I agree that everyone needs this primitive in their toolbox;
> but it's also easy to cut and paste as soon as you need it once.
> (35) Homogeneous Variadics — The example's `3,4,5` and `3,4.0,5` would be
> better with some spaces added.
> (36) SoA to AoS — I think this is a big one. Needs a strawman syntax.
> (37) Unified call syntax — I think this boat has sailed/sunk already.
> Personally I think member functions are great, and it sounds like gamedevs
> have already figured that out too. Needs an example showing why the
> existing solution ("just make it a member") doesn't suffice for someone's
> needs.
> As with (24) and (32) and (33), I suspect that this bullet point is
> motivated by chasing after a faddish perception of what's "modern" (avoid
> the preprocessor, use std::byte, everything should use unicorn
> initialization, everything should be a free function) rather than any
> particular software-engineering need.
> (38) "ifdef-like if constexpr" needs an example. I don't understand what
> "needs to be valid" means here, or what doesn't work today.
> (39) "Conversions should be mostly free." Should rephrase as "mostly
> cost-free" or something, to avoid confusion with free-function conversion
> operators or whatever.
> (40) "bool functions on vectors" — Does this mean filtering, like a
> "gather" operation? Or something else?
> (41) Opt-In UB on Unsigned Overflow — I believe this can be done in a
> library. Has any contributor actually experimented with this? If someone
> provided them with a header-only library with a UB-on-overflow `ouint32`,
> `ouint16`, etc., would they actually try it out and provide feedback?
> I almost certainly won't be at the telecon tomorrow, but I hope these
> comments are useful.
> –Arthur
> On Tue, Sep 7, 2021 at 10:56 AM Patrice Roy via SG14 <
> sg14_at_[hidden]> wrote:
>> Let's do this then. See attached.
>> Remember: it's not a complete document yet (missing pieces), but it comes
>> from our game programming friends and users, and represents a collection of
>> things those I had the pleasure to speak with think would make C++ better
>> for them. I hope it will lead to interesting discussions.
>> Cheers!
>> Le mar. 7 sept. 2021 à 10:50, Michael Wong <fraggamuffin_at_[hidden]> a
>> écrit :
>>> Thanks Patrice, I think this document is of great interest to many
>>> people. Its entirely up to you but usually ahead of meeting sharing will
>>> enable more meaningful comments.
>>> I personally think this is likely one of those landmark document since
>>> the initial document from EA that started this group.
>>> Either way, thank you for pulling this together from several major game
>>> companies and I know everyone should be aware this is a WIP and a call for
>>> collaboration.
>>> On Tue, Sep 7, 2021 at 10:13 AM Patrice Roy <patricer_at_[hidden]> wrote:
>>>> I plan to attend too; I have two concurrent meetings to juggle but I
>>>> will try to migrate to SG14 as early as possible.
>>>> I have an incomplete but thick (30-ish pages) document to discuss, but
>>>> I would simply introduce it and make it available to SG14 for study and
>>>> discussion at a later meeting, since (a) too short a notice for discussion
>>>> tomorrow and (b) it's still missing a few examples.
>>>> Michael : do you want me to share that document before the meeting or
>>>> should I wait, since it will be more of an informational point than a
>>>> technical discussion for tomorrow?
>>>> Cheers!
>>>> Le mar. 7 sept. 2021 à 09:48, Jens Maurer via SG14 <
>>>> sg14_at_[hidden]> a écrit :
>>>>> On 07/09/2021 08.58, Andrzej Krzemienski via SG14 wrote:
>>>>> > Hi SG14,
>>>>> > I plan to attend the meeting on Sep 8, and present P2388R1 (Minimum
>>>>> Contract Support: either Ignore or Check_and_abort <
>>>>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r1.html
>>>>> >).
>>>>> Michael Wong, I assume this is happening, then?
>>>>> Jens
>>>>> > Regards,
>>>>> > Andrzej
>>>>> >
>>>>> > wt., 7 wrz 2021 o 04:38 Michael Wong <fraggamuffin_at_[hidden]
>>>>> <mailto:fraggamuffin_at_[hidden]>> napisał(a):
>>>>> >
>>>>> > Thanks all, all these topics sound great for Games this week our
>>>>> Sept 8 meeting. If Patrice or Andrez plan to be there to present, I will
>>>>> set an agenda for this meeting. As it is Games this month, I would call on
>>>>> one of the Games chair to lead.
>>>>> >
>>>>> > Thank you.
>>>>> >
>>>>> > On Fri, Sep 3, 2021 at 10:28 AM Tjernstrom, Staffan via SG14 <
>>>>> sg14_at_[hidden] <mailto:sg14_at_[hidden]>> wrote:
>>>>> >
>>>>> > +1____
>>>>> >
>>>>> > __ __
>>>>> >
>>>>> > *From:*SG14 [mailto:sg14-bounces_at_[hidden] <mailto:
>>>>> sg14-bounces_at_[hidden]>] *On Behalf Of *John McFarlane via SG14
>>>>> > *Sent:* Friday, 03 September, 2021 10:23
>>>>> > *To:* Low Latency:Game
>>>>> Dev/Financial/Trading/Simulation/Embedded Devices <
>>>>> sg14_at_[hidden] <mailto:sg14_at_[hidden]>>
>>>>> > *Cc:* John McFarlane <john_at_[hidden] <mailto:
>>>>> john_at_[hidden]>>; Gašper Ažman <gasper.azman_at_[hidden] <mailto:
>>>>> gasper.azman_at_[hidden]>>; Andrzej Krzemienski <akrzemi1_at_[hidden]
>>>>> <mailto:akrzemi1_at_[hidden]>>
>>>>> > *Subject:* Re: [SG14] No call tomorrow Aug 11____
>>>>> >
>>>>> > __ __
>>>>> >
>>>>> > Ahead of the agenda for next Wednesday's meeting going out,
>>>>> can I add P2388R1 - Minimum Contract Support: either Ignore or
>>>>> Check_and_abort <
>>>>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r1.html>
>>>>> for review? Andrzej would like to present it to the group and gather more
>>>>> feedback in person.____
>>>>> >
>>>>> > __ __
>>>>> >
>>>>> > On Wed, 11 Aug 2021 at 01:38, Michael Wong via SG14 <
>>>>> sg14_at_[hidden] <mailto:sg14_at_[hidden]>> wrote:____
>>>>> >
>>>>> > Hi all, due to a well deserved summer vacation, many of
>>>>> our chairs are unavailable. Unless there is some topic which is urgent, we
>>>>> plan to cancel tomorrow and move it to the following future dates:____
>>>>> >
>>>>> > __ __
>>>>> >
>>>>> > Aug 11, 2021 02:00 PM ET/1800 UTC: Games Cancelled____
>>>>> >
>>>>> > Sep 8 , 2021 02:00 PM ET/1800 UTC: Games ____
>>>>> >
>>>>> > Oct 13, 2021 02:00 PM ET/1800 UTC: Embedded ____
>>>>> >
>>>>> > Nov 10, 2021 02:00 PM ET/1800 UTC: DST
>>>>> change/cancelled____
>>>>> >
>>>>> > Dec 8, 2021 02:00 PM ET/1800 UTC: Finance/Low
>>>>> Latency ____
>>>>> >
>>>>> > __ __
>>>>> >
>>>>> > Cheers.____
>>>>> >
>>>>> > _______________________________________________
>>>>> > SG14 mailing list
>>>>> > SG14_at_[hidden] <mailto:SG14_at_[hidden]>
>>>>> > https://lists.isocpp.org/mailman/listinfo.cgi/sg14 <
>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg14>____
>>>>> >
>>>>> >
>>>>> >
>>>>> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>>>>> >
>>>>> > IMPORTANT: The information contained in this email and/or
>>>>> its attachments is confidential. If you are not the intended recipient,
>>>>> please notify the sender immediately by reply and immediately delete this
>>>>> message and all its attachments. Any review, use, reproduction, disclosure
>>>>> or dissemination of this message or any attachment by an unintended
>>>>> recipient is strictly prohibited. Neither this message nor any attachment
>>>>> is intended as or should be construed as an offer, solicitation or
>>>>> recommendation to buy or sell any security or other financial instrument.
>>>>> Neither the sender, his or her employer nor any of their respective
>>>>> affiliates makes any warranties as to the completeness or accuracy of any
>>>>> of the information contained herein or that this message or any of its
>>>>> attachments is free of viruses.
>>>>> > _______________________________________________
>>>>> > SG14 mailing list
>>>>> > SG14_at_[hidden] <mailto:SG14_at_[hidden]>
>>>>> > https://lists.isocpp.org/mailman/listinfo.cgi/sg14 <
>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg14>
>>>>> >
>>>>> >
>>>>> > _______________________________________________
>>>>> > SG14 mailing list
>>>>> > SG14_at_[hidden]
>>>>> > https://lists.isocpp.org/mailman/listinfo.cgi/sg14
>>>>> >
>>>>> _______________________________________________
>>>>> SG14 mailing list
>>>>> SG14_at_[hidden]
>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg14
>>>> _______________________________________________
>> SG14 mailing list
>> SG14_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/sg14

Received on 2021-09-07 18:20:56