Earlier quoted context omitted.
{fmt} used to support pre-C++11 compilers that didn't have variadic templates. It was a pain to emulate variadics but it wasn't impossible.
Wow, I don't know that! I would be curious to know how they did it.
The C23 edition of Modern C
331–340 of 360 posts
Re: The C23 edition of Modern C
#332> The storage order, the endianness, as given for my machine, is called little-endian. A system that has high-order representation digits first is called big-endian. Both orders are commonly used by modern processor types. Some processors are even able to switch between the two orders on the fly. Calling big endian "commonly used by modern processor types" when s390x is really the only one left is a bit of a stretch…
POWER is bi-endian. In recent versions, Linux on POWER is little-endian (big-endian Linux on POWER used to be popular, until all the distros switched some years back), while AIX and IBM i are big-endian.
AIX and IBM i are probably not quite as alive as IBM mainframes are, but AIX is still arguably more alive than Solaris or HP/UX are, to say nothing of the dozens of other commercial Unix systems that once existed. Likewise, IBM i is just hanging on, yet still much more alive than most competing legacy midrange platforms (e.g. HP MPE which has been officially desupported by the vendor, although you can still get third party support for it.)
Re: The C23 edition of Modern C
#333Earlier quoted context omitted.
C: int foo(int a[]) { return a[5]; } int main() { int a[3]; return foo(a); } > gcc test.c > ./a.out Oops. D: int foo(int[] a) { return a[5]; } int main() { int[3] a; return foo(a); } > ./cc array.d > ./array core.exception.ArrayIndexError@array.d(1): index [5] is out of bounds for array of length 3 Ah, Nirvana! How to fix it for C: https://www.digitalmars.com/articles/C-biggest-mistake.html
You need to take the address of the array instead of letting it decay and then size is encoded in the type: int foo(int (*a)[6]) { return a[5]; } int main() { int a[3]; return foo(&a); } Or for run-time length: int foo(int n, int (*a)[n]) { return (\*a)[5]; } int main() { int a[3]; return foo(ARRAY_SIZE(a), &a); } /app/example.c:4:38: runtime error: index 5 out of bounds for type 'int[n]' https://godbolt.org/z/dxx7Ts…
Re: The C23 edition of Modern C
#334Earlier quoted context omitted.
> If I want complicated, I would just pick C++ which I typically would never want In my opinion, complexity doesn't scale linearly like this. Sometimes, in fact often times, having more complex tools means a simpler process and end result. It's like building a house. A hammer and screwdriver are very simple. A crane is extremely complex. But which simplifies building a house? A crane. If I wanted to build a house wit…
In my experience, complex tools encourage fluffy programming. You mention a generic container; if I were using C, I just wouldn't use a generic container; instead, I'd specify a few container types that handle what needs handled. If there seem to be too many types, then I immediately start thinking that I'm going down a bad architecture path, using too many, or too mixed, abstraction layers, or that I haven't broken…
Also, I wouldn't be saying this if people didn't constantly try to recreate C++-isms in C. Which sometimes you need to do. So, then you have this strange amalgamation that kind of works but is super error prone and manual.
I also don't necessarily agree that C's constraints encourage better design. The design pushes far too much to runtime, which is poor design from a reasoning point of view. It's very difficult to reason about code when even simple data models require too much indirection. Also, the severely gimped type system means that you can do things you shouldn't be able to do. You can't properly encode type constraints into your types, so you then have to do more validation at runtime. This is also slightly improving, starting with _Bool years ago.
C++ definitely is a very flawed language with so, so many holes in its design. But the systems it has in place allows the programmer to more focus on the logic and design of their programs, and less on just trying to represent what they want to represent. And templates, as annoying as the errors are, prevent A LOT of runtime errors. Remember, every time you see a template that translates into pointers and runtime checks in C.
Re: The C23 edition of Modern C
#335Earlier quoted context omitted.
You need to take the address of the array instead of letting it decay and then size is encoded in the type: int foo(int (*a)[6]) { return a[5]; } int main() { int a[3]; return foo(&a); } Or for run-time length: int foo(int n, int (*a)[n]) { return (\*a)[5]; } int main() { int a[3]; return foo(ARRAY_SIZE(a), &a); } /app/example.c:4:38: runtime error: index 5 out of bounds for type 'int[n]' https://godbolt.org/z/dxx7Ts…
\* what operator is this? I have never seen it. Where can I read about it?
Re: The C23 edition of Modern C
#336Most important aspect of C is its portability. From small microcontrollers to almost any computing platform. I doubt that any new version of C will see that much adoption. If I want to live on cutting edge I would rather use C++2x or Rust rather than C. Am I missing something? What benefit this supposedly modern C offers?
Won't any llvm/gcc supported target get the new version of C automatically? You won't get it in the vendor-modified ancient gcc toolchain for some other arch though.
Also most companies making those platforms are not good at updating their toolchains. Expecting developers to compile their own toolchain, that is unsupported by platform vendor, is too much to ask.
Also GCC dropped support for certain architectures along the way, and even if you are willing to compile your own toolchain, it may not work for you.
Re: The C23 edition of Modern C
#337Earlier quoted context omitted.
C++ can seamlessly include C89 headers. The C library headers for libraries I write often include C11/C99 stuff that is invalid in C++. Even when they are in C89, they are often incorrect to include without the include being in an `extern "C"`.
Extern "C" around the prototypes is mandatory, otherwise your linker will search for C++ symbols, which cannot be found in the C libraries you pass it.
Re: The C23 edition of Modern C
#338Earlier quoted context omitted.
Some idiomatic C code to copy a string (I'm not saying this is good C code, but it's just an example): while(*d++ = *s++) ; On the Motorola 68000 (based somewhat on the PDP-11) the code would look like: loop: move.b (a0)+,d0 move.b d0,(a1)+ bne loop while on the x86 line, it would be: loop: mov al,[rsi] mov [rdi],al inc rsi ; extra instruction! inc rdi ; extra instruction! cmp al,0 jne loop Yes, there are better ways…
> loop: move.b (a0)+,d0 move.b d0,(a1)+ ... > loop: mov al,[rsi] mov [rdi],al This hurts my brain. When we invent time machines I'm going to use it to go back and slap whoever at intel came up with that operand order.
al = [rsi]
[rdi] = alRe: The C23 edition of Modern C
#339Earlier quoted context omitted.
You can do anything in C that you want to. Of course one can make v-tables and all of that, and even do inheritance. But having the "class" keyword is nice. Having built in support for member functions is nice. Sometimes a person just wants the simplicity of C++ 2003. (In reality I was working on a project where our compiler only supported C++ 2003 and we had a UI library written in C++ 2003 and honestly pure C UI li…
> You can do anything in C that you want to. How about destructors?
Re: The C23 edition of Modern C
#340Earlier quoted context omitted.
Why do you "unfortunately"?
It's like using a sledgehammer for a picture hook. I think QT is a great tool, and it solves this problem nicely, but it's a full blown framework, and if you're already using something else - particularly if it's something "light" like SDL, or just a platform specific library like Win32, it's an awful lot to pull in (plus compile times, licensing, etc).