News for hackers. Stuff that matters.
Re:Why Not Just Do Simple C++ RAII in C? by gary_0 on Wednesday May 22, 2024 @02:52PM (#40444695)
In other words, C structs and C++ structs are not the same thing (although C++ can usually handle C structs too). C structs are Plain Old Data. C++ structs are "objects" and there are pages and pages of rules in the C++ Standard about what that means, and there's no way the C Standard can incorporate all that. And you can't drag any C++ struct/class features into C without dragging in all those rules with them.
Re:Why Not Just Do Simple C++ RAII in C? by stonemetal12 on Wednesday May 22, 2024 @03:09PM (#40444904)
Yep. The only difference between struct and class in C++ is that class defaults to private while struct defaults to public.

100% of the using structs like they are C structs vs using class as objects is cultural not a part of the language.

Re:Why Not Just Do Simple C++ RAII in C? by gary_0 on Wednesday May 22, 2024 @04:07PM (#40445736)
Any similarly of keyword naming between C and C++ is purely coincidental. :P

C++ is somewhat unique in that it started out as a few extra features on top of C before gradually splitting off and mutating into a totally separate programming language.

Re:Why Not Just Do Simple C++ RAII in C? by pjmlp on Friday May 24, 2024 @04:09AM (#40464053)
"Unique" in a world where Objective-C, Objective-C++, Groovy, and TypeScript exist.
Re:Why Not Just Do Simple C++ RAII in C? by gary_0 on Friday May 24, 2024 @08:16AM (#40465385)
What I meant wasn't that it was a language that was compatible with an earlier language. Groovy just compiles to the JVM; lots of things do. TypeScript is just JavaScript with type safety; Python did that too. Objective-C was just NeXT attempting to make the ugliest-looking programming language possible and they succeeded immediately.

But Cfront was released circa 1983 and you basically just wrote C, but it added a bit of new syntax that generated extra C behind the scenes. Object-oriented programming was still fetal in 1983! It didn't get really hyped until the mid-90's. So C++ kind of mutated for decades as this gross appendage on C until it became this whole separate blob that ate half of programming. It was 15 years later when the C++98 "standard" started trying to reign in Dr. Stroustrup's monster.

Then in 2005 we threw away all our textbooks that were like "Look! `Apple` derives from `Fruit`! `Car` derives from `Engine`! This is going to change the world!" because adding object-orientedness to everything became uncool when our bosses became fans of Java. But by this point the C++ blob had taken on a life of its own...

So yeah. Very few programming languages have a story as long and insane as C++.

Re:Why Not Just Do Simple C++ RAII in C? by pjmlp on Friday May 24, 2024 @11:12AM (#40467021)
Objective-C was originally a macro processor just like CFront on top of C.

Objective-C++ likewise on top of CFront.

Until like with CFront, they became selfhosted compilers.

Groovy code is Java code, regardless of targeting the JVM, the same syntax is supported and extended with dynamic capabilities.

Object Pascal was created for Lisa project, exactly in 1983.

Tom Love and Brad Cox created Objective-C in 1984.

Re:Why Not Just Do Simple C++ RAII in C? by SAHChandler on Wednesday May 22, 2024 @04:04PM (#40445700)
The public vs. private aspect also affects inheritance. structs publicly inherit from base types by default, classes privately inherit from base types.
Re:Why Not Just Do Simple C++ RAII in C? by kazinator on Thursday May 23, 2024 @01:00AM (#40450637)
Support for POD (plain old datatype) structs in C++ is definitely part of the language.
Re:Why Not Just Do Simple C++ RAII in C? by chipdart on Thursday May 23, 2024 @01:34AM (#40450830)
> 100% of the using structs like they are C structs vs using class as objects is cultural not a part of the language.

I think this take is completely wrong. There is nothing cultural about it. C++ was created as a strict superset of C, and thus from the inception it supported all features made available in C. This design goal remains true up to this day, and only started to diverge relatively recently when C was updated to include features that were not supported (yet) by C++.

When someone declares a plain old struct in C++, they are declaring a struct that is perfectly compatible and interoperable with C. This is by design. From the inception.

Re:Why Not Just Do Simple C++ RAII in C? by mianos on Thursday May 23, 2024 @02:59AM (#40451397)
What if, after 20 years of C++, you spend 10 years doing python, only to go back to C++ and realise that all this private/protected stuff is a crock and most of the time you are doing real work you just use struct and start typing your C++, virtual functions, constructors, destructors etc?

Just asking, for a friend.

Re:Why Not Just Do Simple C++ RAII in C? by josefx on Thursday May 23, 2024 @03:49AM (#40451777)
> you spend 10 years doing python, only to go back to C++ and realise that all this private/protected stuff is a crock

Just a friendly reminder that two leading underscores wont protect your member functions in C++. Even if people insist that those are totally not supposed to be private in python.

Re:Why Not Just Do Simple C++ RAII in C? by nhatbui on Thursday May 23, 2024 @04:06AM (#40451908)
I think OP meant discarding public/private constructs entirely, no protection, like in python.
Re:Why Not Just Do Simple C++ RAII in C? by gpderetta on Thursday May 23, 2024 @04:52AM (#40452241)
Except python started mangling double underscore in a futile attempt to implement private members/methods.
Re:Why Not Just Do Simple C++ RAII in C? by Doxin on Thursday May 23, 2024 @06:00AM (#40452721)
Using double underscore is advised against, and the name mangling is largely considered a mis-feature these days. Most style guides will tell you to use a single underscore to mark something as not for public consumption.

Of course neither double nor single underscore will stop anyone who wants to touch your privates badly enough. Which is big part of the python philosophy: You're not stopped from doing inadvisable things. Instead there's a strong culture around writing "pythonic" code, which largely avoids these pitfalls.

Re:Why Not Just Do Simple C++ RAII in C? by eru on Thursday May 23, 2024 @06:11AM (#40452794)
And neither does C++'s 'private' stop any other code from messing with your data, either, if they want to do that badly enough.
Re:Why Not Just Do Simple C++ RAII in C? by Doxin on Friday May 24, 2024 @04:10AM (#40464057)
I'm not super familiar with C++, but I imagine you'd need some chicanery to access privates, while in python you can just use them by name.
Re:Why Not Just Do Simple C++ RAII in C? by eru on Sunday May 26, 2024 @01:22AM (#40479940)
Well, you can always cast and access stuff by memory address.
Re:Why Not Just Do Simple C++ RAII in C? by mianos on Monday May 27, 2024 @02:42AM (#40488279)
I can't rally upvote this without breaking the rules about obscenities. But I'll give it a :)

In python, if any of this gives you an trouble you can just replace the stuff in the class dict with your own functions. You don't even need to cast.

Re:Why Not Just Do Simple C++ RAII in C? by mianos on Thursday May 23, 2024 @05:08AM (#40452345)
The underscore prefix is more about communication. It's not a bad convention as it makes you feel a bit dirty when you are using them outside a class, but, do what you want, we are consenting adults.

Whenever I say "I'm no longer attached to all that private stuff", people always reply, "wait until you work on a large code base". I work on a million line+ code base. Whatever.

This argument aside, I'm not a total philistine. RAII is awesome but C++ is full to the boot with crusty stuff to keep the compatibility. I always feel there is a language better than anything trying to come out.

Re:Why Not Just Do Simple C++ RAII in C? by gpderetta on Thursday May 23, 2024 @05:26AM (#40452461)
Python will literally mangle the names of double underscore members by prefixing them with the class name, to make it harder to access from the outside, so it is not just about communication.

These days I'm for minimalism, most of my structs are aggregates of public members, but sometimes you really want to make sure to maintain the invariant that your array pointer and your size field are in sync.

Re:Why Not Just Do Simple C++ RAII in C? by steveklabnik on Thursday May 23, 2024 @01:59PM (#40457817)
> This design goal remains true up to this day, and only started to diverge relatively recently when C was updated to include features that were not supported (yet) by C++.

This is not really the case. See https://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B for a non-exhaustive list.

It is true that both sides agree that compatibility is an important goal, but it's only a goal, not something that's 100% the case.

Re:Why Not Just Do Simple C++ RAII in C? by chipdart on Thursday May 23, 2024 @01:21AM (#40450745)
> In other words, C structs and C++ structs are not the same thing (although C++ can usually handle C structs too). C structs are Plain Old Data. C++ structs are "objects" and there are pages and pages of rules in the C++ Standard about what that means, and there's no way the C Standard can incorporate all that.

I think this glances over what structs actually are in C++, and unwittingly portrays them as something different.

Structs in C++ are definitely exact like structs in C. Or they can be, if that's what you're aiming for. If you include a C header file that defines a struct in a C++ program, you build it, and you use instances of that struct to pass them to C programs, everthing just works.

The detail you need to be mindful of is that C structs support a subset of all the features supported by C++ classes, and once you start to use those features C++ also allows implementations to forego some constraints.

If you expect to use a struct in C++ but still define it in a way that you make it include features that are not supported in C then you can't pin that on the language.

https://learn.microsoft.com/en-us/cpp/cpp/trivial-standard-l...

Using C-like structs is a very common use case, to the point that the standard explicitly defines the concept of standard layout and builds upon that to specify the concept of a standard layout type. A struct/class that is a standard layout type, which means it's a POD type, corresponds exactly with C structs. They are explicitly defined in terms of retaining interoperability with other languages.

Re:Why Not Just Do Simple C++ RAII in C? by rramadass on Thursday May 23, 2024 @06:07AM (#40452764)
Exactly. This is one of the basic things (i.e. PODs) you learn in C++ that i am surprised the gp didn't know of it. I myself have written systems with C-structs/C-api and wrapped the same C-structs (by deriving) in C++ classes (being careful with any introduced vptr/vtable) to happily provide/extend C-code/libraries via C++ apis.
Re:Why Not Just Do Simple C++ RAII in C? by gary_0 on Thursday May 23, 2024 @06:42AM (#40453018)
Of course I know about the POD idiom. You and chipdart are misunderstanding me because there's a tension between how the C++ Standard defines things and how C++ gets used in real life. Because strictly speaking, the Standard doesn't really have a concept of POD[0]. What it does have is "trivial" classes and the concept of object lifetime. For instance, if your class/struct isn't trivially_copyable and you memcpy it like a C struct, you're in Undefined Behavior country. If your class/struct is such that you must observe C++'s lifetime rules, but you are writing its fields by casting a char pointer to some bytes, that's UB.

But yes, if you make extra sure (under threat of footgun) that your struct only has simple types in it and doesn't use virtual or define any ctors/dtors or use protected/private or use inheritance and all of its members follow those rules etc etc, maybe you can treat it like a C struct. But the C++ Standard is telling a different story.

Keep in mind, I'm not blaming you for ignoring all these complications if at the end of the day the compiler seems to give you the behavior you expect. But the fun of C++ is that it's kind of two programming languages in one: the language the Standard defines, and the language the typical programmer thinks it is.

[0] There was std::is_pod, but it was deprecated because it doesn't reflect how the Standard actually defines things. A bit of a cruel joke, dangling that in front of us and then yanking it away.

Re:Why Not Just Do Simple C++ RAII in C? by rramadass on Thursday May 23, 2024 @07:14AM (#40453231)
POD is not an idiom. It was an actual specification (in a sense) for interop between C++ and C. Only in the later standards (maybe starting at C++14?) did the committee refine it further as "POD = Trivial + Standard_Layout" but that is just a redefinition without any fundamental change in semantics. So you can happily write C++ code with just your understanding of POD from C++98 in practice and everything will work fine.

References:

1) Trivial, standard-layout, POD, and literal types - https://learn.microsoft.com/en-us/cpp/cpp/trivial-standard-l...

2) No more plain old data - https://mariusbancila.ro/blog/2020/08/10/no-more-plain-old-d...

Re:Why Not Just Do Simple C++ RAII in C? by gary_0 on Thursday May 23, 2024 @07:37AM (#40453425)
They started changing the definitions in C++11 to support move semantics. I don't remember much about C++98, that was decades ago. If that's what the Standard said back then I'll take your word for it, but I wasn't talking about historical C++ Standards.

Keep in mind, my original comment was pretty much just drawing a line through TFA, which also argues that you can't cleanly map C++ object concepts onto C structs. C++ has some backwards compatibility with C obviously but nowadays it's a totally separate language with an independent standards body (for better or worse). Specifying "do what C does" might have flown in 1998 but that changed a long time ago.

Re:Why Not Just Do Simple C++ RAII in C? by rramadass on Thursday May 23, 2024 @10:07AM (#40454939)
I am generally not a fan of the standards committee nor what it is trying to do with the language. The word "Object" used in C++ land has a different meaning than the same word used in C land since there is an "Object Model" in C++ while there is none in C. Hence trying to map C++ object concepts onto C does not even make sense in the general case. But because of C++'s evolution having started as "C with classes" there is some mapping at the set-of-bits level which is where the POD (with all its limitations) comes in.

I am fully with Stroustrup in arguing that C++ should strive for as much compatibility with C as possible in the spirit of the original (see ref. at https://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B...). But sadly the rest of standards committee don't seem to want this which i believe is a huge mistake. On the other side, the C standards committee should be very careful what inspiration they take from C++ in the evolution of the language since it was designed as a "minimal" language which was one of the main factors in its success. Whether people call it "primitive", "well behind other languages" etc. does not matter. You definitely don't want C turning into C++-lite. Hence IMO the conclusions stated in the last few paragraphs of the submitted article are quite right.

Re:Why Not Just Do Simple C++ RAII in C? by gary_0 on Thursday May 23, 2024 @10:41AM (#40455336)
In my experience the number of C++ developers with nice things to say about the Committee is... very small.

In a way, the whole C++ endeavor was doomed from the start. C was old and pragmatic and vague, a "portable assembly", and it was a shaky foundation to build C++ on top of. When the Standard tried to tighten things up, it just got more lopsided, full of hacks to fix hacks. But the alternate universe where C++ had a more pragmatic, laissez-faire design going forward probably isn't any better; maybe the "standard" would have become "do whatever GCC does"--or in the Darkest Timeline, "do whatever MSVC does".

I disagree that C++ "respecting its C roots" is viable. The C++11 and later Standards were trying to make the best of a bad situation, and that required leaving C behind because the C way of doing things doesn't fit with a higher-level language like contemporary C++. Especially when the language has multiple implementations that need to compile the same code the same way. The "C with classes" days are long over for most of us who have to use libraries expecting std::vector, smart pointers, and exception handling. We live in mortal fear of compiler writers smiting us for innocent things like punning through a union.

> You definitely don't want C turning into C++-lite

I agree. Trying to quickly hack classes or templates or whatever back on top of C would just start the whole C++ nightmare over again.

Re:Why Not Just Do Simple C++ RAII in C? by rramadass on Thursday May 23, 2024 @11:53AM (#40456287)
> In a way, the whole C++ endeavor was doomed from the start ... I disagree that C++ "respecting its C roots" is viable.

Hey! Them's fighting words! :-) "C++ as a better C" (which is what it started as) was/is/always will be needed and necessary. It gave you the best of both low-level and high-level worlds with full control and just enough complexity. Instead of implementing structs full of function pointers to design dynamic dispatch object models you just had the compiler do that for you while still retaining full control over other aspects. I still have some manuals that came with SCO Unix one of which was on the then newfangled C++ language. It had one chapter by Stroustrup himself (his original paper probably) on the C++ object model showing how vptrs/vtables are implemented and thinking it neat that the compiler did it for you. Also templates were just glorified macros then with none of the shenanigans that you see today. Hence moving from C to C++ was easy and its usage and popularity exploded. But with the infusion of lots of people into C++ land people who were not aware of the original vision/design/compatibility goal of the language started asking for the inclusion of more and more OO and modern language features. The result? The standards committee reinventing the language from C++11 onwards(and changing every freaking 3 years) and alienating the old C++ folks who made it popular in the first place. No doubt there are some benefits like increased design space and modern programming techniques but am not sure whether the increased complexity makes it all worth it. For me it is still C++98 with the addition of the STL and some simple generic programming techniques which is the sweet spot.

Re:Why Not Just Do Simple C++ RAII in C? by celrod on Thursday May 23, 2024 @03:09PM (#40458677)
> We live in mortal fear of compiler writers smiting us for innocent things like punning through a union.

C++20 introduced `std::bitcast`, so I appreciate alias analysis getting all the help it can.

Re:Why Not Just Do Simple C++ RAII in C? by rkangel on Thursday May 23, 2024 @06:13AM (#40452804)
> Using C-like structs is a very common use case

Not true. Using C structs themselves in C++ is very common - when you include the C header file, the relevant declarations are wrapped in "extern "C" {}" which gives structs C semantics. You can do this because C++ is backwards compatible with C.

Most of the time when you use a struct in C++ you're just ignoring most of the capabilities of objects (which is fine!). If you declare a struct in C++, you're getting an object. The only difference between the struct and class keywords in C++ is the default privacy of the members.

Re:Why Not Just Do Simple C++ RAII in C? by gpderetta on Thursday May 23, 2024 @09:37AM (#40454566)
A C++ structure has exactly the equivalent semantics of a C structure if it exists. Extern "C" only affects linkage of functions. It has no effect on structure definitions.
Re:Why Not Just Do Simple C++ RAII in C? by OskarS on Thursday May 23, 2024 @09:48AM (#40454685)
It absolutely does not. A C++ structure is a much richer object: it can have custom copying, moving and assignment behaviours, it can have vtables, it has RAII, etc. That's the whole point about the "object model" in the article: C++ has it, C does not.

What I think you're trying to say is "a POD structure with no custom behavior is essentially identical in C and C++". That is mostly true, though if the struct contains a union, C++ has stricter UB rules (there might be other differences as well, but that's the one I can think of at the moment).

Re:Why Not Just Do Simple C++ RAII in C? by gpderetta on Thursday May 23, 2024 @11:01AM (#40455586)
What I'm saying is that extern "C" has no effect on structure compatibility.