3 ms·
Errr, C++ can do this. It just requires analysis to do it in some cases (not all). As a trivial example, the point about const is wrong (at least as far as i
by DannyBee 10y ago
Errr, C++ can do this.
It just requires analysis to do it in some cases (not all).
As a trivial example, the point about const is wrong (at least as far as i understand it).
you can const cast stuff, but you still can't modify it, to do so is UB:
Modifying a const object through a non-const access path and referring to a volatile object through a non-volatile glvalue both result in undefined behavior.
So yeah.
As for the abi, any abi arguments are silly.
really.
the compiler can always clone the function, rename it, and do what you want.
or inline it.
or ....
If it really matters, you'd also just change the ABI.
There is no C++ standard ABI.
There's one a lot of compilers use.
If we could get x% better performance using a different one, people would do that :)
The corollary is "If you think you can only get x% better performance by doing that, you are probably wrong".
(I'm excluding things that are low level abis, like x32, etc, since we are talking about language abis)
- Galanwe 10y ago+1 for the ABI part. Nothing prevents you in C++ to use multiple ABIs depending on how you plan to build / distribute your library. You can use e.g. `fastcall` inside you library, because you know that you will be using the same compiler to build it and don't expose these symbols publicly, and use `cdecl` for the public facing functions.
- snovv_crash 10y agoEspecially for anything templated or inlined. Seriously, I'm getting sick of these Rust/Go/Hype is better than $competitor because $edgecase. Yes, but what if I want to do sparse matrix manipulation? What if I want to interact with hardware, and set registers? What if I want to use the library Bob wrote back in 2001, because it is really well tested and we've never encountered a bug since 2003?
- stestagg 10y agoRust is actually lovely for peripheral register manipulation. Check out the zinc project for some great examples. Likewise, linking to external libraries is trivial. I'm not saying that rust is better than any other language. But those examples aren't factors in this religious debate
- pathsjs 10y agoLinking to external C libraries is trivial. If the library is written in C++ and does not expose a C api, things can become much more difficult
- snovv_crash 10y agoNever mind using a C++ header-only library.
- int_19h 10y agoThe point about const is not wrong. What you said about const is true if, and only if, the object was originally const - i.e. you can't do this: const int n = 1; const_cast<int&>(n) = 2; However, when the function receives a pointer or reference to const, it doesn't know whether the referenced object is originally const or not. It only knows that it cannot write through that pointer; but someone else still might be able to do so. Example: int n = 1; void foo() { n = 2; } int bar(const int& x) { int y = x; foo(); return y + x; } bar(n); Even though x is reference to const here, the compiler has to do two reads from x here, because foo can - indeed, does - change the value referenced by x. Worse yet, the function can often change it itself via aliasing: int n = 1; int bar(const int& x, int& y) { y = x; return x; } bar(n, n); Again, this is perfectly legal. The problem is that both C and C++ lack a way to say "this is a pointer or reference to something that is immutable", as opposed to "... something that you can't mutate". The other problem is that C++ (but not C, thanks to "restrict") lacks a way to say "the object referenced by this pointer or reference is not aliased in any other respect that matters to this function". Rust, OTOH, does let you say that something that's referenced is immutable. In fact, it is the case by default. So the compiler can aggressively optimize around the fact. In C++, they can only optimize as well when the compiler can do a full program analysis, and determine that the referenced value is immutable in practice. Which can be hard to do for non-trivial programs, and outright impossible to do across dynamic library boundaries.
- gpderetta 10y agotemplate<class T> struct const_ { const T value; }; const_<T>& freeze(T&); T& thaw(const_<T>&); do_something(const_<T>& x) { /* the language guarantees that x can't be mutated from anywhere */ }
- pjmlp 10y agoYou can cast away const.
- gpderetta 10y ago'value' is a const qualified object, not a const qualified reference. If you cast away the const and write to the object you are into UB, ergo the compiler can assume that isn't done. Note that the trick still doesn't help much in practice: GCC conservatively still won't optimize based on const qualification of values.
- berkut 10y agoExactly - C++ compilers definitely can do this, and it's one of the things ICC's noticeably better than GCC and LLVM at, especially where intrinsics are involved. If you have a struct/class type union wrapper for SIMD instrinsics which contains something like __m128 and pass that by reference, GCC and LLVM will often implement this as an effective pointer onto the stack (or wherever the struct is). ICC can often detect this, and keep it as a by-value __m128, which is often more efficient and keeps stuff in the registers.
- Const-me 10y agoAnd MSVC has __vectorcall keyword for ICC-like calling convention that passes arguments in those SSE registers.