Live data from Hacker News

Ill-Advised C++ Rant, Part 2

codersnotes.com

31–40 of 66 posts

Re: Ill-Advised C++ Rant, Part 2

#31

I found it funny how many of the complaints were really about the preprocessor. Many of them have already been addressed. If you don't like defining a macro as "do { ... } while (0)", try using an inline function. Even C has inline functions nowadays, and that's been true for more than a decade.

If you could write it as a function why would you be writing a macro in the first place?

That's an obvious question. A lot of macros should be functions.

The most common case I'm aware of are functions like toupper(), islower(), ispunct(), etc. that the C Standard allows to be macros for performance (the actual work in the function is testing or setting a single bit, and the overhead of a function call really matters in that case).

Inline functions would have the same performance, and you can get a pointer to them without doing the #undef rigamarole you see when a macro definition might muck things up.

Re: Ill-Advised C++ Rant, Part 2

#32

Earlier quoted context omitted.

If you could write it as a function why would you be writing a macro in the first place?

That's an obvious question. A lot of macros should be functions. The most common case I'm aware of are functions like toupper(), islower(), ispunct(), etc. that the C Standard allows to be macros for performance (the actual work in the function is testing or setting a single bit, and the overhead of a function call really matters in that case). Inline functions would have the same performance, and you can get a point…

Inline functions aren't guaranteed to be inlined. There are compiler specifics that add stronger hints to the optimizer to inline but behavior isn't always consistent from one compiler to the next. The only portable way to force something to be inlined is to use a macro.

Re: Ill-Advised C++ Rant, Part 2

#33

Earlier quoted context omitted.

That's an obvious question. A lot of macros should be functions. The most common case I'm aware of are functions like toupper(), islower(), ispunct(), etc. that the C Standard allows to be macros for performance (the actual work in the function is testing or setting a single bit, and the overhead of a function call really matters in that case). Inline functions would have the same performance, and you can get a point…

Inline functions aren't guaranteed to be inlined. There are compiler specifics that add stronger hints to the optimizer to inline but behavior isn't always consistent from one compiler to the next. The only portable way to force something to be inlined is to use a macro.

Why is it essential that anything is inlined? Maybe if the compiler isn't inlining it had a good reason for that? Maybe it has some understanding of the trade off between specialisation and code size for these particular functions which you don't.

Re: Ill-Advised C++ Rant, Part 2

#34
post #26
post #20

I tend to agree, but gave up on fixing C++ a decade ago. I hope Rust is the future; it deals with all these issues. But Rust seems to be starting out at the complexity level it took C++ two decades to achieve.

> Rust seems to be starting out at the complexity level it > took C++ two decades to achieve. You say this every time that Rust is compared to C++ (which is a lot!), but I have yet to see an elaboration. What in particular are you talking about?

As someone trying to learn/experiment with Rust, the syntax is pretty complex. Now granted it comes with some benefits, and I realise there are a limited number of characters available to use (at least that everyone in the world has on their keyboards), but stuff like the lifetime char ' are IMO way too easy to mistake when quickly glancing at code for strings.

But maybe that's just me.

Re: Ill-Advised C++ Rant, Part 2

#35
post #26
post #20

I tend to agree, but gave up on fixing C++ a decade ago. I hope Rust is the future; it deals with all these issues. But Rust seems to be starting out at the complexity level it took C++ two decades to achieve.

> Rust seems to be starting out at the complexity level it > took C++ two decades to achieve. You say this every time that Rust is compared to C++ (which is a lot!), but I have yet to see an elaboration. What in particular are you talking about?

Rust doesnt have objects, but otherwise is very compelling. I still use C++ but I'm also looking forward to the day (soon) where I can use Rust instead for many projects. With more languages coming to LLVM I expect there will be other solutions as well.

C++ took years until it got a ranged for loop. It was so important you had frameworks like Qt providing their own preprocessor to support this functionality. C++ is a language that has a lot of baggage to be backwards compatible and incorporates multiple turing complete languages. When was the last time functionality was removed from C++ to support a better design?

Why the hell do we still have header files with raw includes? That's about as sophisticated as copy and paste. The macro preprocessor is stuck in the 70s, probably because the C++ grammar is so hard to parse to write something better. Most template metaprogramming outside of generics is garbage that could be replaced with a better preprocessor and usually the result of premature optimization or avoiding deficiencies in the language and creates custom ad-hoc knowledge that isn't easily transferred to other programmers.

Rust has a better preprocessor, cleaner design, no includes, and generics without template metaprogramming. I shouldn't have to mention it but it has things that most modern languages do like ranged for loops, flexible switch/match statements, clojures, and automatic type inference. It doesnt have virtual methods, template metaprogramming, or exception handling.

If you're curious, I'd recommend flipping through the syntax guide, there are a lot of well designed concepts:

https://doc.rust-lang.org/book/syntax-and-semantics.html

Re: Ill-Advised C++ Rant, Part 2

#36
post #34
post #26

Earlier quoted context omitted.

> Rust seems to be starting out at the complexity level it > took C++ two decades to achieve. You say this every time that Rust is compared to C++ (which is a lot!), but I have yet to see an elaboration. What in particular are you talking about?

As someone trying to learn/experiment with Rust, the syntax is pretty complex. Now granted it comes with some benefits, and I realise there are a limited number of characters available to use (at least that everyone in the world has on their keyboards), but stuff like the lifetime char ' are IMO way too easy to mistake when quickly glancing at code for strings. But maybe that's just me.

Do you happen to be using a syntax highlighter that doesn't recognize the single apostrophe and therefore highlights a huge quantity of code as though it were a string? (This syntax is familiar to OCaml, so it's not like editors are incapable of recognizing this, it's just not usually the default.) This was an annoyance back before text editors had modes for Rust syntax, but I haven't seen it in the wild in years.

If not, then it's simple to know when something is a lifetime vs. when it's a character literal, even if you're quickly scanning. Lifetimes appear in type declarations, so they'll be in struct definitions and function signatures. Character literals can't appear in those positions (and character literals are extremely rare in Rust already, so much so that in the past I actually petitioned to have them removed!).

I also don't think that Rust's syntax is of comparable complexity to C++'s, e.g. the number of uses `const` in C++ (and on a technical level, Rust's grammar is much simpler than C++'s), so I don't think that syntactic complexity is what Animats was referring to.

Re: Ill-Advised C++ Rant, Part 2

#37
post #35
post #26

Earlier quoted context omitted.

> Rust seems to be starting out at the complexity level it > took C++ two decades to achieve. You say this every time that Rust is compared to C++ (which is a lot!), but I have yet to see an elaboration. What in particular are you talking about?

Rust doesnt have objects, but otherwise is very compelling. I still use C++ but I'm also looking forward to the day (soon) where I can use Rust instead for many projects. With more languages coming to LLVM I expect there will be other solutions as well. C++ took years until it got a ranged for loop. It was so important you had frameworks like Qt providing their own preprocessor to support this functionality. C++ is a…

Indeed, but you're refuting Animats' comment, and you and I happen to be in agreement that Rust and C++ are nowhere comparable in terms of language complexity (largely due to C++'s C-compatibility and the burden of 30 years of backwards-compatible language evolution).

My original question still stands, because I'm curious to know how he perceives Rust's complexity to be equivalent to that of C++'s.

Re: Ill-Advised C++ Rant, Part 2

#38

Earlier quoted context omitted.

Inline functions aren't guaranteed to be inlined. There are compiler specifics that add stronger hints to the optimizer to inline but behavior isn't always consistent from one compiler to the next. The only portable way to force something to be inlined is to use a macro.

Why is it essential that anything is inlined? Maybe if the compiler isn't inlining it had a good reason for that? Maybe it has some understanding of the trade off between specialisation and code size for these particular functions which you don't.

Because compilers need to work for any program, thus tend to the best common denominator, while you, the programmer, can design something for a particular use case. In this case, hot loops - at best a compiler could know about the runtime intensity by using a runtime profile and then deciding that, yes, in this case it's actually best to inline something. But having a compile -> link -> run (profiled) -> compile -> link workflow is much too bothersome and slow (so most don't do this) and it's much more manageable to sit down and turn on your brain when programming. This stance of "no premature optimisation" has gone overboard IMO.

Re: Ill-Advised C++ Rant, Part 2

#39
post #34
post #26

Earlier quoted context omitted.

> Rust seems to be starting out at the complexity level it > took C++ two decades to achieve. You say this every time that Rust is compared to C++ (which is a lot!), but I have yet to see an elaboration. What in particular are you talking about?

As someone trying to learn/experiment with Rust, the syntax is pretty complex. Now granted it comes with some benefits, and I realise there are a limited number of characters available to use (at least that everyone in the world has on their keyboards), but stuff like the lifetime char ' are IMO way too easy to mistake when quickly glancing at code for strings. But maybe that's just me.

No, it's not just you. The more I look at Rust, the less I like.

-- leaving off the semicolon on the last statement causes that to be the return value of a function.

-- functions can't capture free variables in lexical scope. They need an entirely different type and syntax for that (closures).

-- try reading some non-trivial Rust code that uses generics - it's just as incomprehensible and unmaintainable as C++.

It's a huge disappointment.

Re: Ill-Advised C++ Rant, Part 2

#40

Earlier quoted context omitted.

Inline functions aren't guaranteed to be inlined. There are compiler specifics that add stronger hints to the optimizer to inline but behavior isn't always consistent from one compiler to the next. The only portable way to force something to be inlined is to use a macro.

Why is it essential that anything is inlined? Maybe if the compiler isn't inlining it had a good reason for that? Maybe it has some understanding of the trade off between specialisation and code size for these particular functions which you don't.

If the compiler doesn't inline something, you generally have no way of knowing if the reason was had good or bad.
Post reply on HN