MaxEW707 wrote:

I appreciate the discussions. I know I have a tendency to get ranty in my 
writing so I just want to be clear that I mean no malice.
I can further explain my side.

> Include times
> Modules should ease that pain

I don't know how else to make it clear that we will never be including std 
headers from our core library headers and within the core engine itself. The 
include times are a non-starter. If the verdict is just use std, we are going 
to continue just marking these functions as `always_inline` and live with the 
worse code gen than a builtin but still better than a function call.

Even if libc++ becomes tolerable we have to deal with msvc stl, libstdc++, 
libc++, SCE stl, and vendor forks of libc++ that I will not mention since this 
specific company is super duper litigious over the most minor things.
If I could have an attribute that solves my problems without header includes 
and I can chuck it on the implementations in our core libraries then I am 
golden instead of trying to work around various std libraries.

I also want to highlight that we in particular have a wide range of platform 
support.
We were just able to get rid of VS2015 early 2023. We also finally removed 
GCC4.8 late 2022.
We still have to ship on a custom toolchain of VS2017 msvc for Xbox One.
We have game teams that are also on the latest VS2022.
Our macOS/iPhone support is quite wide as well.
SCE is very quick to upgrade their clang so we are on Clang 16 now if my memory 
is correct there on SCE. Any change to libc++ does not help SCE STL or the 
other vendors shipping their own fork of clang + libc++. A lot of these vendors 
will upgrade clang but not libc++ as well.

On our Linux servers we have such a variety of distros and GCC/Clang versions.

Regarding modules. Try moving the titanic that is [insert favourite game here 
that is shipping content every year].
Now try moving 3+ titanics.
Try moving that when you still have platforms that cannot move past VS2017.
Plus some vendors have no intention, as far as I am aware, of supporting 
modules in their vendor libraries which do include `<utility>` and such for 
move/forward.

Apple Clang + Xcode still don't support modules last I checked. We haven't 
upgraded to Xcode 15 yet.

We have our own build system generator. We have our own package management 
system. We have our stuff working well with PCH files where needed.
We have all the infrastructure set up to promote fast builds from the core 
libraries down the stack. I don't foresee us even considering modules for 10+ 
years.

> More general observations on the "using c++ without the STL thing":
> I don't think this is a major consideration of the language/standard 
> committee going forward.
> Reflection will also have a dependency on the STL

I don't want to speak for my peers but I think I can speak to the general 
sentiment of my community.
This is why among many many many other reasons SG14 failed and why a lot of us 
in the game dev community have just given up.
Some are at companies that do not allow any form of open source contributions 
or participation in the C++ discourse. That seems to be changing.
Thankfully I am at a company that does allows me to make these contributions 
here on my free time, LLVM license makes it easy for me to do so and I have the 
means to try to push them through. Selfishly for me but also for the game dev 
community at large.
Especially nowadays where we can basically ship with clang on almost every 
platform, a change in clang affects our entire ecosystem. It seems gone are the 
days of custom vendor compilers for every platform with EDG as the frontend.

I have followed the Reflection TS and its fine. At every game company I worked 
at our reflection needs are so esoteric that we are going to continue writing 
our own with our own code generators.
Almost every single game engine has its own way to do some form of dynamic 
casting, similar reasons that llvm also seems to have its own infrastructure 
from reading the docs, and that casting is usually very tightly integrated with 
the engine's reflection system.
Trying to highlight that in general a lot of these papers, for the language 
itself or the std, will never solve the esoteric needs of us or handle the 
esoteric platforms that we support. Not everything uses the BSD sockets API for 
example. Win32 is considered BSD compared to the stuff I've seen.
We just want a systems language that allows us to accomplish system level tasks 
while still retaining a lot of really useful core features like templates, easy 
support for intrusive data structures, control over allocations, etc.

As mentioned above our Linux servers use a variety of distros. The server 
software running in our datacentres still uses all our core libraries like all 
the game software but has more liberty with what game teams can run. We are 
less strict on what the various amount of server services are allowed to use 
since that software is usually tightly written for one specific platform.

For example I know, https://github.com/confluentinc/librdkafka, is a common 
library used in some backend services across the games industry which has a C++ 
interface with std. I've seen kafka used for log aggregation, game server 
monitoring, login queue monitoring, etc in backend services.
A lot of times these are installed from the distros package manager or some 
vendor apt-get link.
It is a lot easier for me to say hey if you want to use these cool facilities 
just `apt-get install clang-18` and build with that or even build the compiler 
ourselves.
There is no way I am going to be building the software with latest libc++ and 
not the platform libstdc++ especially since std may be in use here for some 
third-party libs.
Like I said we have more pull and constraints on the engine proper but modern 
multiplayer games have a loooooooooooooot of services :).
At the very least we try to wrap these vendor and/or third-party libraries so 
the std includes are only in a subset of source files especially if we do not 
have the time and/or man-power to re-write said libraries ourselves.

>  If you are not using a standard library implementation at all and instead 
> act as your own standard library vendor

I first want to talk about freestanding. We cannot ship with freestanding on 
consoles and mobile.
Especially consoles we will fail TRC(technical requirements checklist). We 
cannot at all muck with the environment on consoles, rightfully so, nowadays 
compared to when everyone in the industry would hack them up back in the day.
Android has its own infrastructure with Bionic.

As I tried to explain above we do not use the std but we are forced to use it 
in some cases. It is very likely that std headers will get included after our 
headers transitively in platform specific files.

For example since it is super dead now, Stadia. All of Stadia's APIs had std in 
them.
So `ControllerInput_*.Stadia.cpp` platform specific files that abstract 
Stadia's APIs would end up including std.

A lot of game studios use https://github.com/syoyo/tinyexr to handle OpenEXR 
image formats when converting from RAW assets to Editor assets and/or Editor 
assets to Runtime assets.
That lib also uses std in its header and interface. And since that library is 
used on the tooling side it isn't a high priority on my list to re-work it.

There are many more examples especially vendor code from some platforms that 
aren't public that we cannot at all control.

Our style guide requires system/library headers to be included after our 
headers and I don't even want to start the bikeshedding on changing that...

> @philnik777 Do std::move/ std::forward etc actually need an abi tag? Maybe we 
> should simply not set a tag given that clang / gcc replace call to these 
> functions.

As @philnik777 highlighted the std implementers have to implement it 
pedantically and guard against users doing insane things like taking the 
addressof `std::move`. We do not have those constraints and would rather not 
have to deal with them personally.
I am happy I am not in that boat :).

> I think we could also extend the set of std functions replaced in the front 
> end if we can show it would have measurable compile times improvements (ie 
> to_integer, as_const, to_underlying, etc).

Maybe an attribute name change would suffice here. Something like 
`[[clang::cast_to_return_type]]` which is basically what the builtins do.
This attribute will work on any function that returns a pointer or reference 
and has a single argument that is a pointer or reference.
It tells the compiler that the function body will just cast the input type to 
the return type.

The function could something crazy like
```
template<class T, class U>
[[nodiscard]] constexpr auto&& forward_like(U&& x) noexcept
{
    constexpr bool is_adding_const = 
std::is_const_v<std::remove_reference_t<T>>;
    if constexpr (std::is_lvalue_reference_v<T&&>)
    {
        if constexpr (is_adding_const)
            return std::as_const(x);
        else
            return static_cast<U&>(x);
    }
    else
    {
        if constexpr (is_adding_const)
            return std::move(std::as_const(x));
        else
            return std::move(x);
    }
}
```
or as simple as
```
template<class T>
std::remove_reference_t<T>&& MyMove(T&& t) { return 
static_cast<std::remove_reference_t<T>&&>(t); }

template<class T, SFINAE(...)>
T* MyAddressOf(T& arg) { return 
reinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<const volatile 
char&>(arg))); }
```

The warnings not working with this proposed attribute is not a big deal to me. 
We already don't get them with our implementation of these meta functions. I 
intend to fix these warnings anyways and I have a PR already for one here: 
https://github.com/llvm/llvm-project/pull/76646.

static assertions possibly not firing such as 
`static_assert(!is_lvalue_reference<_Tp>::value, "cannot forward an rvalue as 
an lvalue");` inside forward is not a big deal for me. We already do not get 
this for our inlined static casts.
Currently if the builtin is `BIforward`, clang has a special check for this 
inside `SemaTemplateInstantiateDecl.cpp` with
```
case Builtin::BIforward:
      // Do not treat 'std::forward' as a builtin if it takes an rvalue 
reference
      // type and returns an lvalue reference type. The library implementation
      // will produce an error in this case; don't get in its way.
```
Maybe this is an easy solve with the proposed `[[clang::cast_to_return_type]]`. 
Not sure. I need to dig through that part of the code in clang which I haven't 
touched yet.

I think I addressed all of the statements above. Please let me know if I missed 
any :).

https://github.com/llvm/llvm-project/pull/76596
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to