Remix.run Logo
▲ uecker 5 hours ago

Having used C++ a lot in the past, I think the mess in C++ is way worse. I also contribute to projects that introduce C++ into a C code base, and I really wish they hadn't done this.

Although there are C features I like that I would need to remove before introducing C++ to a codebase, so this may not always be so simple.

▲Panzerschrek 4 hours ago | parent [-]

> the mess in C++ is way worse

What is mess in C++? Yes, it has some shady parts and is more complex than C, but this complexity provides expressiveness and type safety. And you can always use only features from C++ you find useful.

> also contribute to projects that introduce C++ into a C code base, and I really wish they hadn't done this.

What is problematic in these projects other than unfamiliarity of C++ for developers previously used only C?

▲_gabe_ 3 hours ago | parent | next [-]

> What is mess in C++?

Just a couple examples:

How do you make a shallow copy of an object in C++, how do you do the same thing in C? Knowing I can just memcpy _any_ struct in C and have a valid shallow copy is pretty huge.

How do you create a stable ABI in C++? How do you make one in C? In C, knowing that all my exported functions will mostly just work and be stable as long as I don’t change the interface is also huge and allows you to create cross language bindings pretty trivially.

▲Panzerschrek 3 hours ago | parent | next [-]

> How do you make a shallow copy of an object in C++

Shallow copies aren't generally possible for classes storing something indirectly, since it violates ownership semantics. That's not how things are done in C++.. Operator = is usually used for making copies, which is optimized to memcpy for POD structures, but for something more complex may perform extra work for doing an actual deep copy.

> How do you create a stable ABI in C++

It's a complex topic. Basic ABI for calling functions is identical to C. But one need to keep in mind, that type layouts and internal implementations of library types (like containers) may differ from implementation to implementation and from version to version.

> knowing that all my exported functions will mostly just work and be stable as long as I don’t change the interface

Nothing prevents you doing this in C++. You can have C-style external interface and use all goods of C++ internally.

▲variadix 2 hours ago | parent | prev [-]

You can’t necessarily do that in C either, it depends on if your object is in a container that relies on pointer stability. Intrusive linked lists are common in C and they get broken by this, for example.

▲lelanthran 3 hours ago | parent | prev | next [-]

> And you can always use only features from C++ you find useful.

Ah, the old "programmers just need to be more disciplined when using C++".

Yeah, C programmers have never seen that argument before...

▲uecker 3 hours ago | parent | prev [-]

My macro-vector types are type safe. In fact this is the point.

I do not think C++ is more expressive or type safe.

▲ranger_danger an hour ago | parent [-]

In C, assigning the return value from malloc() to a specific type merely produces a warning:

  $ echo -ne "#include <stdlib.h>\nint foo() { return malloc(42); }" | gcc -xc -fsyntax-only -c -
  <stdin>: In function ‘foo’:
  <stdin>:2:20: warning: returning ‘void *’ from a function with return type ‘int’ makes integer from pointer without a cast [-Wint-conversion]
Whereas in C++ it's a hard error:

  $ echo -ne "#include <stdlib.h>\nint foo() { return malloc(42); }" | gcc -xc++ -fsyntax-only -c -
  <stdin>: In function ‘int foo()’:
  <stdin>:2:26: error: invalid conversion from ‘void*’ to ‘int’ [-fpermissive]
Does this not count as "more type safe" to you?