Live data from Hacker News

C constructs that still don't work in C++

lospino.so

141–150 of 182 posts

Re: C constructs that still don't work in C++

#141
post #99

Earlier quoted context omitted.

Yes, a static_cast would be safe, but then most C++ seems to use a C-style cast because it is less clunky and then is less safe than the corresponding C code. The issue is not that the downcast is unsafe (it is, but once you have a void pointer you already accepted this), but that it becomes even less safe by adding a C-style cast. It is also not clear what is gained by forcing programmers to add a cast. Void pointer…

> but then most C++ seems to use a C-style cast If C++ programmers do not use modern safety features, that's really their fault. C-style pointer casts should be flagged in code review. > but that it becomes even less safe by adding a C-style cast. At least in C++ there is a safer option. If you really want to be on the safe side, you can even to a dynamic_cast (assuming your code base allows RTTI). > It is also not c…

Lack of ergonomics around static_cast is language problem. The "most safe" of the casts should not be this verbose.

Re: C constructs that still don't work in C++

#142
post #134

Earlier quoted context omitted.

LOL. You do know ISO/IEC 29500 exists right? ISO agreed that despite there being an existing, popular, broadly supported and open XML document standard they should define Microsoft's proprietary alternative OOXML as an international "standard". They even held votes repeatedly until the voters gave the "correct" answer... no worry about "industry donations" there.

I remember the story, but it was considered outrageous for a reason.

I'm sure it would be considered "outrageous" when the same happens outside an SDO too.

Re: C constructs that still don't work in C++

#143
post #134

Earlier quoted context omitted.

I remember the story, but it was considered outrageous for a reason.

I'm sure it would be considered "outrageous" when the same happens outside an SDO too.

Well, one could consider Mozilla's management of firefox to be outrageous, but then, Google pays, so what to expect?

Re: C constructs that still don't work in C++

#144
post #73

Earlier quoted context omitted.

The correct choice IMHO is type-erasure. It does not necessarily have overhead, because optimizers can specialize or devirtualize. Of course, this my depend on how you implement your language, but in C this works nicely. The problem with monomorphization is that it leads to exponential expansion, which later passes of the compiler can not unify again (at least this is much harder than not expanding in the first place…

Type-erasure does have an inherent overhead. Sure, optimizations can be made, but they can be fickle and specialization is basically implicit monomorphization. Using C macros to replicate Rust's monomorphism has several drawbacks: they are inherently unhygienic, even in comparison to Rust's own; you can't set type-bounds; they aren't even a part of C proper, etc. I prefer Rust's approach with the choice between gener…

What inherent overhead does type-erasure have? The optimizer can always specialize just like for monomorphization. The difference is that it does not have to do this. Monomorphization specializes everything before the optimizer even has a chance to look the the code. So it fundamentally can not have advantages, only restrictions.

C macros are certainly a proper part of C and one can also certainly add type-bounds. But yes, they are not ideal. Still, if one wanted to do this, one could certainly improve them a lot for type-generic programming. I would prefer this to having macros, generics, a const expression sublanguage, and vtables.

Re: C constructs that still don't work in C++

#145
post #136

Earlier quoted context omitted.

> if you provide your own, this is no problem. If just "providing my own" would help why wouldn't the stdlib benefit too? You're going to have to spell out what you think can actually work here if you want me to believe there's "no problem".

It would also, but nobody cares enough because qsort is already fast enough for most things, and if you cared it is simply enough to do yourself. Are you doubting that C compilers can devirtualize function calls? Here is a small example that illustrates this. The compiler dervirtualizes all calls than folds the result: https://godbolt.org/z/E6cMMr8vx

[dead]

Re: C constructs that still don't work in C++

#146
post #144

Earlier quoted context omitted.

Type-erasure does have an inherent overhead. Sure, optimizations can be made, but they can be fickle and specialization is basically implicit monomorphization. Using C macros to replicate Rust's monomorphism has several drawbacks: they are inherently unhygienic, even in comparison to Rust's own; you can't set type-bounds; they aren't even a part of C proper, etc. I prefer Rust's approach with the choice between gener…

What inherent overhead does type-erasure have? The optimizer can always specialize just like for monomorphization. The difference is that it does not have to do this. Monomorphization specializes everything before the optimizer even has a chance to look the the code. So it fundamentally can not have advantages, only restrictions. C macros are certainly a proper part of C and one can also certainly add type-bounds. Bu…

The inherent overhead of type-erasure is the vtable. Which is funny, because you said you prefer one over the other at the end, when they are basically synonymous. The compiler may choose to devirtualize and specialize, but that isn't guaranteed. If you want this behavior, &dyn does the exact same thing.

Specialization provides more opportunities for optimizations, whereas proper type-erasure (which bars specialization optimizations) doesn't due to lack of type information.

"C macros" are a part of the preprocessor, which runs before the actual C compiler. As such, it lacks all semantical information the C compiler would have at that point, such as function implementions. In practice, macros in C serve two purposes: manipulating C source code (which Rust macros can also do, but with more hygiene); specialization polymorphism, but worse (in which both Rust's generics and C++ templates do better).

Re: C constructs that still don't work in C++

#147
post #144

Earlier quoted context omitted.

What inherent overhead does type-erasure have? The optimizer can always specialize just like for monomorphization. The difference is that it does not have to do this. Monomorphization specializes everything before the optimizer even has a chance to look the the code. So it fundamentally can not have advantages, only restrictions. C macros are certainly a proper part of C and one can also certainly add type-bounds. Bu…

The inherent overhead of type-erasure is the vtable. Which is funny, because you said you prefer one over the other at the end, when they are basically synonymous. The compiler may choose to devirtualize and specialize, but that isn't guaranteed. If you want this behavior, &dyn does the exact same thing. Specialization provides more opportunities for optimizations, whereas proper type-erasure (which bars specializati…

The vtable can be removed in all cases where you specialize by monomorphization, so the overhead compared to it is not really inherent.

Type-erasure can be undone by specialization. In contrast, monomorphization specializes the code first, at which point it becomes much more difficult to unify it again.

Sorry, my comment about preference was badly phrased: What I meant is that I prefer to make macros better, than having all the different but partially overlapping techniques in the same language. This is the complexity I am complaining about in both C++ and Rust.

Re: C constructs that still don't work in C++

#148
post #144

Earlier quoted context omitted.

What inherent overhead does type-erasure have? The optimizer can always specialize just like for monomorphization. The difference is that it does not have to do this. Monomorphization specializes everything before the optimizer even has a chance to look the the code. So it fundamentally can not have advantages, only restrictions. C macros are certainly a proper part of C and one can also certainly add type-bounds. Bu…

The inherent overhead of type-erasure is the vtable. Which is funny, because you said you prefer one over the other at the end, when they are basically synonymous. The compiler may choose to devirtualize and specialize, but that isn't guaranteed. If you want this behavior, &dyn does the exact same thing. Specialization provides more opportunities for optimizations, whereas proper type-erasure (which bars specializati…

I just noticed you said "The compiler can always specialize". That's indisputably false. That only happens if the compiler has enough information to infer the concrete type at the call point. Conditionals, collections, or anything that may throw doubt about original type info and their function implementations can (and normally will) disable specialization.

Re: C constructs that still don't work in C++

#149

Earlier quoted context omitted.

The inherent overhead of type-erasure is the vtable. Which is funny, because you said you prefer one over the other at the end, when they are basically synonymous. The compiler may choose to devirtualize and specialize, but that isn't guaranteed. If you want this behavior, &dyn does the exact same thing. Specialization provides more opportunities for optimizations, whereas proper type-erasure (which bars specializati…

I just noticed you said "The compiler can always specialize". That's indisputably false. That only happens if the compiler has enough information to infer the concrete type at the call point. Conditionals, collections, or anything that may throw doubt about original type info and their function implementations can (and normally will) disable specialization.

It can always specialize where you could do monomorphization.

Re: C constructs that still don't work in C++

#150

Earlier quoted context omitted.

I don't get your point at all. C++ has different casting operators (static_cast, const_cast, reinterpret_cast) that are strictly safer than C-style casts. Also, let's not forget that implicit casts between unrelated pointer types is only a warning in C. Fortunately, modern C compilers started treating it as an error by default because it caused so much harm: https://gcc.gnu.org/gcc-14/porting_to.html . In C++ this wa…

> implicit casts between unrelated pointer types is only a warning in C A warning in C has the meaning of a "stern warning" aka. "That very much won't work, I warned you!". An error means, "I literally, don't what you mean". Also as far as I know, the C standard only talks about diagnostics.

You are right that the C standard only talks about diagnostics, but this doesn't change the fact that implicit casts between unrelated pointer types are not treated as hard errors.
Post reply on HN