Who wants to see a C replacement?

Started by
62 comments, last by swiftcoder 8 years, 9 months ago

No, you don't have to distribute source files at all. All you have to do is distribute a library in the same way you would distribute a .NET library. There is no source code attached to it. It's a single file.

So basically what you are saying is that if C doesn't meet your needs, just move to a different higher level language that can meet your needs? C meets our needs 90% of the way. Moving to another language will not solve the other 10%. In fact, it would make us go backwards. Let's take a prime example of moving to a higher level language. C -> C#. I lose pointers. Nope, can't do that. C -> Java, same thing. C -> just about any high level language you lose pointers. That fact alone makes those moves not viable. The only logical choice then is moving to C++. C++ does not solve the header issue, but the other higher level languages do. Its a unique problem space that is not solved currently that I can see.

  • The power of C with regards to pointers
  • A heap that can be defragmented but does not require garbage collection. Therefore manual memory management. Garbage collection requires many many more performance critical steps
  • Performance of C
  • Module based compilation ( no headers )

The spur of these suggestions might have been from the situation in my company. However, let me ask you: Would not any one of those features be beneficial to the C language as it is? You can argue "Oh, if you move to xx language, you get this and that" all you want. I can also argue that you lose one thing or another from that list. I am not looking for a trade off.

See I wouldn't really say that. Sure, you are having less work on the typing/definition creation end with only one file. But first of all, there is already addons/IDE-functions for that. Second, the little more typing for each method definition is really not that much. Unless you are writing getter/setter or one-line functions (which again you can always just write inline anyways), copy/pasting the function declaration from the header and putting Class:: between return value and function name is usually the fraction of work it takes to write (plus design) the actual method. Sure, just have a little more overhead, but thats really not that significant in my mind at least. And last point, which is at least where I am going from - for me personally its much more effective to have the seperation between header and source when it goes to maintaining the code. For me its way easier to skim through a small header with only declarations and click on a method and "Goto/Show definition" than if I had the whole source as part of the class declaration, since I have way less sh*t to scroll/skim through. Of course this is all subjective and probably depends on the coding style of the individual programmer, but for me its cool.

You mention some nice IDE features for doing certain things. What about the IDE feature of an outline view? Eclipse and VS both have it. I don't need an extra header file to look at the interface in a consolidated list. If there is any information that is available in a header file, it can just as easily be made available in an outline view.

Advertisement
Sigh.

So there's already like 50 of these things. C++, D, Go, Nim, and Rust are even _popular_ ones, not to mention all the barely-known ones. Not to mention all the languages that don't even pretend to be C-like.

Garbage collection: Garbage collection in its current form is un-operable: However, we have come up with some ideas for garbage collection that would be very good, clean, and would not affect performance in our major use case. Essentially a garbage collector that only runs when you need it to (idle hook) and can be preempted (interrupted) at any time to process higher priority events. Once the system is idle again, the collector resumes where it left off. This is actually possible. The major hurdle is that the C language does not support the reference tracking we need to implement it.


I think you have a major misconception about how GCs work. Also, even in the most modern of GC'd languages, developers working on things like games basically have to avoid half of the language in order to 100% guarantee they do not trigger the GC. It's actually _less_ convenient than using C!

Not that it matters, because a language that helps you track object lifetimes (C++, Rust, D, etc.) gives you automatic memory management without ever needing a GC.

Plus, GC's are totally useless for anything except _memory_ resource management, which is hardly the only resource that needs lifetime tracking, so the non-GC automatic lifetime mangement features are in fact more powerful. Which is exactly why lnaguages like C#, Python, D, and so on had to add half-measures like 'with' statements and IDisposable objects (which unlike in C++ or Rust, are easy to misuse and accidentally leak resources, or at least lose the very necessary predictable destruction behavior).

Get rid of header files.


C++ is gaining this feature. Kinda.

Class model: Right now we employ a very simple class model using C. Basically we 'derive' from structures. This means you can cast any structure to any other structure as long as the structure derives from it. Deriving from a structure means that the first member of a new structure is always the base of another structure. Will need to expand upon this idea; however, the ability to have classes, member functions, etc..


So you want a brand new language that has none of the type theory innovations after the 1970's and also somehow without many of the type theory innovations of the 50's? Neat.

We don't need all the fancy stuff coming in the new specs of the C++ language: lambdas, generics, templates... unnecessary. KISS.


... What? You don't want lambdas, but yet you complain about not having callbacks? You don't want generics or templates, so you apparently want to manually rewrite every single container because sometimes you need your list to store ints sometimes a list of floats and sometimes one of pointers?

The only part of "KISS" worth remembering is "stupid" because it's a worthless phrase. You don't _want_ a simple language. You want simple daily development. There _must_ be complexity somewhere. Either you are responsible for it (as in C) or the language helps you remove it (as in C++/Rust/D/etc.). e.g., the GC you asked for is _insanely_ complex to do well and any language with GC is far more complex than C, but it does heavily simplify the code you have to write when using the language. You can't "keep it simple." All you can do is move the complexity around, and preferably move it away from the user.

My understanding is that C++ is an impossible language to make good IDE features for (intellisense).. but it looks like its super easy to make intellisense for C# type languages.


It's not easy, no, but definitely possible. Heck, we can make powerful type-aware IDEs for dynamically-typed languages. Computational science is neat.

The preprocessor makes it kinda hard, but that's just as much of a pain in C as in C++. And you need some kind of tool like that, so either (a) you keep the preproc and all its warts, (b) you develop an integrated macro feature for the language and make it far more complex like Rust or D, or (c) you ignore the problem and require users to use some unofficial non-standardized third-party tool that will have even worse IDE integration.

I'm not looking to reinvent the wheel on any formats. For example, in our system we compile C code for an ARM platform which then produces an ELF file with DWARF debugging. We are only concerned with the language / IDE here.


Funny. The archaic nonsense of the C linkage model is actually one of the things I am _so_ ready for someone to replace. smile.png

... which modules do in quite a few languages that have them, e.g. C#'s Assemblies.

This is going to be your downfall.

You are incorrect in your understanding of why the C API (headers) is separate from its ABI (libraries).


I don't follow your argument at all. C++ is gaining modules. There's nothing incompatible with modules and the classic C linkage model.

Plus, there's all kinds of things you do about that linkage model to make it better. The static library approach used by every platform is infuriating, and in no way necessary.

You can have pre-compiled libraries that include metadata for compiling (again, see C# Assemblies). You can have platform-neutral pre-compiled libraries that are finalized at application compile time with no degradation in runtime speed nor compile speed over header-only or source-only libraries.

API and platform ABI and the C linkage model are _entirely_ separate things.

I even miss the separation when working with templated classes which I'm used to writing inline.


Nothing in the world stops you from separating them still. You don't have to put the method definitions inline, you can either put them at the end of the file or even in a separate file (e.g., a .inl file that gets included at the end of the .h file).

You can even take the approach used by folks like the BitSquid guys where the class template definition is completely sparated from the function template definitions in two separate headers; this lets your class headers include minimal type definitions while leaving all the complicated function machinery to headers only included by source files, which can cut down compile times quite a bit. (And incidentally, a proper module system would make this basically automatic.)

The C++ module systems in the works doesn't force you to remove the header setup either, btw. The idea of the proposed C++ module systems is that you can still write separate header and source files but then define a module that merges the public headers together into a fast metadata "module" that simplifies and speeds up compilation and linking for dependent modules.

It's a half-step to C#-style modules that leaves some problems and annoyances unsolved, but can be extended in the future after real-world implementation experience and in the mean time the C++ module system solves some of the most obnoxious problems of the C compilation model.

and I need to navigate 8 folders up, then 8 folders down in the "includes" folder to get the header and see it there, then have the two files open next to each other to make sense out of the whole thing.


You need better tools. I often jump between the header and related source in projects with equally crazy directory structures. VS+VAX makes it trivial. The only time I even need to pay attention to the directory structure is when I'm adding a new file.

Sean Middleditch – Game Systems Engineer – Join my team!

Oy, how long ago did you write that response? I even went and updated my OP like half an hour or more ago, yet you still glean incorrect information from it.

I think you have a major misconception about how GCs work. Also, even in the most modern of GC'd languages, developers working on things like games basically have to avoid half of the language in order to 100% guarantee they do not trigger the GC. It's actually _less_ convenient than using C!

Not that it matters, because a language that helps you track object lifetimes (C++, Rust, D, etc.) gives you automatic memory management without ever needing a GC.

Plus, GC's are totally useless for anything except _memory_ resource management, which is hardly the only resource that needs lifetime tracking, so the non-GC automatic lifetime mangement features are in fact more powerful. Which is exactly why lnaguages like C#, Python, D, and so on had to add half-measures like 'with' statements and IDisposable objects (which unlike in C++ or Rust, are easy to misuse and accidentally leak resources, or at least lose the very necessary predictable destruction behavior).

No misconception. What you meant to say is your misconception for 1. Not reading all of the posts where I say what I want is not actually GC and 2. for not looking at the latest OP where I corrected some of my wording.

So you want a brand new language that has none of the type theory innovations after the 1970's and also somehow without many of the type theory innovations of the 50's? Neat.

No, I am merely stating the addition of a class model, I do not know what it would entail which is why I said it would need to be expanded. It could be similar to any of the numerous languages out there picking from a single one or several. Never did I state it was something new. ASSuming based on the limited information in my original statement makes an a** out of you and ..... you.

... What? You don't want lambdas, but yet you complain about not having callbacks? You don't want generics or templates, so you apparently want to manually rewrite every single container because sometimes you need your list to store ints sometimes a list of floats and sometimes one of pointers?

Let me rephrase what I think you meant to say here: "What? I really don't understand what you meant by not having callbacks." That is what you meant to say, because I know for a fact you could not be as simple minded to assume lambdas are the only way to implement callbacks. It's called C linkage. You know.. that thing we put on some C++ member functions to make them conform to the cdecl model or whatever so that they have C linkage and therefore can be specified as callbacks to many C libraries? My gripe is the fact that the way most implementations are done you cannot specify a member function as a callback for something in a C library.

I like the closed mindedness spewing from this statement. Remember I am using C. We do have a linked list implementation that uses something called a void pointer. Yeah? We have to cast it when retrieving data, but it beats the hell out of manually rewriting our linked list for every type that could be stored in it!

So it really looks like we have some contenders for header files here. Huh, I did not know that many people existed that liked them.


When I first started learning C back in the early 90's, I wrote nearly all of my code in headers. Don't know why. It made for an ungodly mess. That wasn't the fault of the header system, but inexperience and lack of knowledge on my part. I find headers a great way to organize files. If I have structs or variables that need to be accessed from multiple source files, what better than a header? Why retype the data in each source file? What do you gain from that, but headaches? If I update a struct in one source file and forget about another, the fun bug hunting begins.

Seriously, how do you plan to do libraries? How do I access the functions without function definitions? What about the necessary data structures? Understand that I am not talking about source libraries that I include in my project as .c files, but compiled static and dynamic libraries. How do I access the library?

Having to maintain a single file versus 2 is clearly less typing and more efficient.


Why don't you write a text-parsing tool that parses your C files and generates the headers from them? Then when you make a change you just run the tool and it updates the headers for you.

Seriously, how do you plan to do libraries? How do I access the functions without function definitions? What about the necessary data structures? Understand that I am not talking about source libraries that I include in my project as .c files, but compiled static and dynamic libraries. How do I access the library?

Ask the .NET developers the same thing, rather the Mono developers since they had a static compilation option for .NET where you could compile things into a static exe.

Seriously? At the time of compilation, all information required is in the library. The library contains metadata, function prototypes and the structure declarations. The library becomes just another input to the compiler just as it is for other module based languages. How do you access functions without function definitions? .NET does it fairly well with its module model.

Why don't you write a text-parsing tool that parses your C files and generates the headers from them?

So what you mean is why not have a tool that 'documents' my source code? Doesn't doxygen already do that? A header file is essentially documentation at this point.

C++ is not an option due to the object instance member function issue. Believe me, this is a monumental issue for us. Our entire application model depends on events and callbacks. Not being able to set callbacks on "application classes" would be devastating.


Correct me if I'm reading this wrong, but you seem to be making a classic mistake here. It's been hinted upthread but I'll be a bit more explicit about it.

Just because C++ has support for classes, doesn't mean that you have to use them.

You can write perfectly valid C++ code without even writing one single class. As if it were C. And still gain many of the other benefits of the language. Same goes for templates, or any of the other C++ constructs you seem to be opposed to.

So your callback objection is therefore invalid: just don't write classes, and everything works.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Seriously, how do you plan to do libraries? How do I access the functions without function definitions? What about the necessary data structures? Understand that I am not talking about source libraries that I include in my project as .c files, but compiled static and dynamic libraries. How do I access the library?

The same way every modern language does. With modules. A magical system by which we provide the public API in the same file as the compiled library. Who'd have thought it was possible to improve on header files?

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Seriously, how do you plan to do libraries? How do I access the functions without function definitions? What about the necessary data structures? Understand that I am not talking about source libraries that I include in my project as .c files, but compiled static and dynamic libraries. How do I access the library?

The same way every modern language does. With modules. A magical system by which we provide the public API in the same file as the compiled library. Who'd have thought it was possible to improve on header files?


I have never seen a library that did not expose the API through a header file. This is new to me. More info?

Correct me if I'm reading this wrong, but you seem to be making a classic mistake here. It's been hinted upthread but I'll be a bit more explicit about it.

Just because C++ has support for classes, doesn't mean that you have to use them.

You can write perfectly valid C++ code without even writing one single class. As if it were C. And still gain many of the other benefits of the language. Same goes for templates, or any of the other C++ constructs you seem to be opposed to.

So your callback objection is therefore invalid: just don't write classes, and everything works.

So you mean just stick with C? Can someone confirm he told me to stick with C please!?

If I am not using THE major feature(s) of the language, the reason for switching to it in the first place, tell me pratel: why would I switch to it?

This topic is closed to new replies.

Advertisement