I wonder which library author would *not* put this disclaimer. And then, if all library authors have to put this disclaimer, simply using this feature would make your code undefined. And it's strange to have a standard feature that makes your code undefined simply by using it.

I think this type of tool is more well suited for compiler extensions. Maybe your compiler vendor sees the practical use and is able to implement such a feature. Your code won't be portable, but I'm guessing if you are intentionally making your code undefined, then you are well beyond that concern.

Breno G.

On Sun, Jul 17, 2022 at 6:07 PM Frederick Virchanza Gotham via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Sun, Jul 17, 2022 at 7:36 PM Robert A.H. Leahy wrote:
>
> Being able to "impose friendship" would create a maintenance nightmare for everyone who writes libraries.


No, it wouldn't. A simple disclaimer:

    "The behaviour of this library is undefined if you impose friendship".

But of course: The use of imposed friendship is evidence that you're
using the 3rd party library in a way in which it wasn't intended to be
used -- so the disclaimer is implicit. Perhaps there could even be a
compiler diagnostic to the effect of:

main.cpp:27:5: warning: member object 'monkey' is marked 'private' in class,
                        but imposed friendship violates interface
27 | obj.monkey = 5;
   | ^~~~~~~~~~~~~~

If I were to write my own library -- for example a 3D graphics library
-- and release it to the public domain, I wouldn't be particularly
worried about how my library will behave when Tom, Dick or Harry edits
my header files. I'm not going to accommodate people editing my header
files, and I'm not going to accommodate imposed friendships.


> Not only would the publicly-visible surface of the library need to be maintained but the internals couldn't
> change because any consumer of the library could have "imposed friendship" and now be depending on the
> precise inner workings of the class. It's the ABI compatibility nightmare except arguably worse.


I propose that one of the requirements for compilers implementing
imposed friendship is that it doesn't change the ABI -- and so other
source files in the project _don't_ need to be recompiled.

What I'm proposing is better than editing the 3rd party header file in
order to change:

    class RS232_Link {
        int monkey;
    };

into:

    class RS232_Link {
        int monkey;
        friend class Friend_RS232_link;
    };

and then writing in your own source file:

    struct Friend_RS232_Link {
        int &monkey;
        Friend_RS232_Link(RS232_Link &arg) : monkey(arg.monkey) {}
    };

    int main(void)
    {
        RS232_Link obj;

        Friend_RS232_Link(obj).monkey = 5;
    }

Obviously we shouldn't use a 3rd party library in ways they weren't
intended to be used -- the author of the library marked a particular
method as 'private' for a good reason -- but we live in the real world
where sometimes it makes sense not to follow a rule or not to follow a
convention. In the few corner cases in which we should violate good
programming practise, it would be much cleaner to simply do this:

    friend<monkey>.obj = 5;

instead of going editing the 3rd party header files. Leaving the 3rd
party header files intact means we don't need to go editing them every
time a new version of the 3rd party library is released.
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals