Live data from Hacker News

The beauty and simplicity of the good old C-style void* in C++

giodicanio.com

71–80 of 182 posts

Re: The beauty and simplicity of the good old C-style void* in C++

#71
post #65
post #62

Many years ago I remember going through the Boost library and seeing C-style casts that seemed entirely gratuitous. I tried replacing them with what I was pretty sure were the equivalent C++ reinterpret_casts, and the result didn't compile. I never did figure it out.

C style cast can be either a static_cast or reinterpret_cast, but it can also be a const_cast or a static+const or reinterpret+const. Finally, it will perform a static_cast that bypasses private inheritance (because the alternative would be to fall back to a reinterpret_cast, which is wrong if the static_cast needs to apply an offset to the pointer)

> a static_cast that bypasses private inheritance (because the alternative would be to fall back to a reinterpret_cast, which is wrong if the static_cast needs to apply an offset to the pointer)

That may well have been it, then. I would think that if it could have been expressed naturally, it would have been.

(I don't think I ever used private inheritance in my own C++ code. I'm not a huge fan of inheritance at all, so.)

Re: The beauty and simplicity of the good old C-style void* in C++

#72
In C++ you'd just do

    template 
    void DoSomething(T const& data);
or if T* is supposed to point to a tightly packed buffer

    template 
    void DoSomething(std::span data);
as the author pointed out. I don't see how that is ugly or more complicated than the original void* approach.

There is no need to pass the size of T or length of the span, former is just a sizeof(T) away and latter is a data.size(); away.

In fact, a lot of codebases would outright ban the uint8_t* and reinterpret_cast trick the author is complaining about via clang-tidy rules.

Re: The beauty and simplicity of the good old C-style void* in C++

#74
post #28

Earlier quoted context omitted.

It could have been there since the beginning, given that open arrays (aka spans) already existed in other languages, and there was even a failed proposal from Denis Ritchie regarding C. The C++ span proposal came from Microsoft, https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p01...

> already existed in other languages This argument is moot. The issue with spans is not that they require cutting edge technology to deliver. Before commenting, perhaps you should research why even Denis Ritchie himself could not sell his idea to C. It's funny how every single idea that's rejected is blindly lauded as brilliant but silenced due to some kind of conspiracy, and only the ideas that emerged are somehow b…

Easy, even one of the author's could not change WG14 mind towards security.

Governments,related cybersecurity agencies, and companies are the ones getting outraged when looking at money spent in cyber attacks due to memory corruption issues.

Re: The beauty and simplicity of the good old C-style void* in C++

#75
post #58
post #47

Earlier quoted context omitted.

Those are ABI. Unless it is inlining them, the overhead is to stay.

ABI changes do happen. gcc had an ABI change in std::string because of C++11. It was long and painful, but everyone survived, the world did not end

Contrary to the FOSS compile from source culture, other platforms have a different point of view on ABI breaks.

Which is why Valve ended up using Proton.

Re: The beauty and simplicity of the good old C-style void* in C++

#76

Earlier quoted context omitted.

> No - if something is UB in the spec, it's UB. A compiler is still free to ignore the spec and declare that something is not UB. However, this is very much compiler based, not platform based. Windows might guarantee that aligned DWORD-sized memory accesses are atomic, but that doesn't mean Clang when compiling for Windows would respect this - but MSVC might.

No, a compiler obviously cannot do this. nothing is undefined behaviour under a known compiler, version, and settings. UB means you can't know what the code does in general not that you can't know what it does in a very specific case.

UB has 2 very different implications:

1. It means that even if your program happens to work, it can't be portable

2. It means that even if your program happens to work today, it might stop working tomorrow when you add some new code, when you change some compiler flags, or when you do even a minor compiler upgrade

Of course, a compiler can't address 1. However, a compiler can very much address item 2. If Microsoft were to say "in MSVC, we define integer overflow to wrap", then they would guarantee that `INT_MAX + 1` will produce `INT_MIN` regardless of any optimization settings, any compiler upgrades, any other changes to the code. Of course, compiling the exact same program with Clang or GCC might cause it to crash or corrupt memory or anything else - but as long as you stuck with MSVC, your program would have perfectly defined semantics.

This is similar to using compiler extensions or intrinsics - they are not portable and not defined by the standard, maybe even explicitly defined to NOT be supported per the standard (such as variable length arrays in C++ in GCC), but they are nevertheless perfectly safe as long as you stick to your chosen compiler.

Edit to add: the integer overflow example is not just a theoretical possibility - lots of C++ compilers provide the `-fwrapv` flag; when using that flag, signed integer overflow is no longer UB for that program, it is defined just the same as unsigned integer overflow.

Re: The beauty and simplicity of the good old C-style void* in C++

#77
post #25

Earlier quoted context omitted.

They did in C, from one of the language authors even, and it was not accepted. https://www.nokia.com/bell-labs/about/dennis-m-ritchie/varar... By the way, both Extended Pascal, Mesa/Cedar and Modula-2 have them, under the name of open arrays. Basically it took Go, C# and others for C++ to finally get its span. C probably never will.

Everybody knows that C++ did not invent the concept of spans and that it was late to the party. It doesn’t change the fact that (presumably) nobody made a proposal to the C++ standard.

Microsoft made the proposal for C++, after Midori project, and Office security improvements.

Which by your comment, you have no clue about how it came to be.

Proposal is linked in another comment of mine.

Re: The beauty and simplicity of the good old C-style void* in C++

#78
post #62

Many years ago I remember going through the Boost library and seeing C-style casts that seemed entirely gratuitous. I tried replacing them with what I was pretty sure were the equivalent C++ reinterpret_casts, and the result didn't compile. I never did figure it out.

To add on top of sibling comment, C style casts are too lose, and the main reason for the new C++ style casts is improved type safety.

So instead of anything goes, there is some additional type checking depending on the type of cast being made.

Re: The beauty and simplicity of the good old C-style void* in C++

#79
>a function that hashes some input data (using SHA-256, or whatever hash algorithm)

Along with padding bytes.

> Why should people complexify and uglify their C++ code with the uint8_t pointer (or std::byte), when void* works just fine??

That was the intention of reinterpret_cast - make ugly code look ugly.

Re: The beauty and simplicity of the good old C-style void* in C++

#80
post #37

I think that the author is right in everything he says and yes, there is beauty in it. However, the antithesis is also correct that there exist better solutions to solve the issues. Both premises hold true. I have an extensive assembler coding background on 6510, M68000, and i486. I had a very hard time accepting that something could be solved faster and more stable in a higher order language while the downside is mo…

One of these days I want to do a "typesafe macro assembler" that actually is the language people think that C is.

It already exists, MASM and TASM, and related derivatives, with high level control flow pseudo instructions and less UB.
Post reply on HN