views:

539

answers:

9

I noticed some not so old VM languages like Lua, NekoVM, and Potion written in C.

It looked like they were reimplementing many C++ features.

Is there a benefit to writing them in C rather than C++?

A: 

C++ is implemented in C. I suspect everyone was following the C++ approach.

Even though modern C++ compilers skip (or conceal) the explicit C++ to C translation as a discrete step, the C++ language has peculiarities that stem from the underlying C implementation.

Two examples.

  • Pointers in addition to references is entirely because of C. References are sufficient, and that's the way Java, Python and Ruby all work.

  • The classes are not first-class objects that exist at run-time because the class is only a way to define the attributes and method functions in the underlying C code. Class objects exist at run-time in Java, Python and Ruby, and can be manipulated.

S.Lott
Why would you say C++ is implemented in C? Can you clarify please? Thanks!
Pablo Santa Cruz
*Was*. Was originally implemented in c. It has long since been bootstrapped.
dmckee
What does it mean for C++ to be implemented in C? A C compiler can be written in any language. MSVC is written in a mix of C and C++, G++ is, as far as I know, C only. LLVM is C++. But any language could be used.
jalf
@jalf he means that C++ used to be written in C and compiled down to a C program.
Unknown
+5  A: 

People are used to C. I have to admit that I'm more likely to write C for my own projects, even though I've been writing C++ since cfront 1.0.

If you want complete control over things, C is a little easier.

Charlie Martin
+3  A: 

It's much harder to be "good" at C++, and until one is good at it they will have a lot of bugs and problems. Now, especially when working on large projects with many people, the chance that one of them won't be good enough is much bigger, so coding the project in C is often less risky. There are also portability issues - C code is much easier to port across compilers than C++.

Tal Pressman
+18  A: 

I know something about Lua.

  • Lua is written in pure ANSI Standard C and compiles on any ANSI platform with no errors and no warnings. Thus Lua runs on almost any platform in the world, including things like Canon PowerShot cameras. It's a lot harder to get C++ to run on weird little embedded platforms.

  • Lua is a high-performance VM, and because C cannot express method calls (which might be virtual or might not) and operator overloading, it is much easier to predict the performance of C code just by looking at the code. C++, especially with the template library, makes it a little too easy to burn resources without being aware of it. (A full implementation of Lua including not only VM but libraries fits in 145K of x86 object code. The whole language fits even in a tiny 256K cache, which you find at L2 on Intel i7 and L1 on older chips. Unless you really know what you're doing, it's much harder to write C++ that compiles to something this small.)

These are two good reasons to write a VM in C.

Norman Ramsey
Would it be possible to convert a subset of C++ into ANSI C automatically? I cringe at the thought of implementing many C++ OOP features and STL containers.
Unknown
Seriously, STL sucks.
hasen j
STL is brilliant (and performant). Fearing virtual methods seems strange given that you're implementing an interpreted language. However, the first one is a good point. Not every platform has a C++ compiler, but you'd be hard pressed to find one that doesn't have C.
jalf
@jalf I agree with you. If you needed to see if a method was virtual or not, you could go to the declaration. I wonder what platforms have a C compiler that don't have a C++ one.
Unknown
@jalf: When you care about performance, you want to avoid indirect calls because the branch-prediction hardware does not do such a great job. And *I* don't want to have to run off to a class declaration to know if a call is direct or indirect.
Norman Ramsey
@Norman: I disagree that templates help in burning resources. Templates allow the compiler to emit *more efficient* code with templates because it has more specific type information. for example, std::sort is often faster that C's quicksort because the compiler can inline the compare function can efficiently implement type safe copying. (whereas qsort cannot make any assumptions about the type since it has to be able to copy objects of any size). I have no argument about the virtual functions.
i think what norman was after is that you can't know what's going on. the very flexibility of templates will serve for the large range of possible performance, depending on what template arguments you provide and how specializations are chosen. In C, i think typical libraries will lay their ways bare and you see what is and what is no good. Of course, this is not an argument against C++. You can write C code in C++ too, if you want, of course
Johannes Schaub - litb
@ilproxyil: Show me the measurements. Having a duplicate, specialized version of every function or method can lead to *poorer* performance. And the compiler doesn't always do a great job specializing, especially when separate compilation is involved. I'm not saying C++ is always bad or always good---just that it's hard to **predict** the costs of the code you write. C benefits from a *very* simple, predictable cost model.
Norman Ramsey
@litb: what you just said :-)
Norman Ramsey
A: 

In many cases, code in C could be much faster than C++. For instance most of the functions in the stdio.c library are faster than iostream. scanf is faster than cin, printf is faster than cout etc.

and VMs demand high performance, so C code makes perfect sense, although the programs would most probably take longer to develop.

Tian Bo
i'm using stdio instead of iostream in my c++ program.
Unknown
eh, and std::sort is way faster than qsort. The iostream library is potentially faster than stdio, assuming you disable sync_with_stdio, but that depends on the implementation. In general, there is no reason why C++ should be slower than C, and often, the opposite is the case. But of course, that requires you to know what you're doing. Misusing C++ will definitely result in slower than necessary code.
jalf
i've this paper tower with 1metre thick walls, and that other tower of stone with 1cm thick walls. I made scientific benchmarks on them, and observed the paper tower is far more stable. Therefor, my next house will be built with paper instead of with stone. srsly
Johannes Schaub - litb
+4  A: 

One obvious answer is interoperability. Any time language X has to call functions defined in language Y, you usually make sure that either X or Y is C (the language C, that is)

C++ doesn't define an ABI, so calling C++ code from another language is a bit tricky to do portably. But calling C code is almost trivial. That means that at least part of your VM is probably going to have to be written in C, and then why not be consistent and write the entire thing in C?

Another advantage of C is that it's simple. Everyone can read it, and there are plenty of programmers to help you write it. C++ is, for good and bad, much more of an experts language. You can do a lot of impressive things in C++, and it can save you a lot of work, but there are also fewer programmers who are really good at it.

jalf
Is C++ really that hard? Also, I always felt it was easy enough to wrap any exported functions with an extern "C" {}
Unknown
C++ is hard to learn *properly*, yes. There are a lot of pitfalls and things that seem to work to the beginner, but is undefined behavior, and may fail unpredictably at any time. It's a big and messy language. Anyway, you're right extern "C" lets you expose your functions using the C abi, but then you're also limited to C-compatible types and functions. And then the question is, why not just write the whole thing in C and avoid the confusion?
jalf
+6  A: 

It looked like they were reimplementing many C++ features.

Are you suggesting it's easier to implement polymorphism in C++ rather than C? I think you are greatly mistaken.

If you write a VM in C++, you wouldn't implement polymorphism in terms of C++'s polymorphism. You'd roll your own virtual table which maps function names to pointers, or something like that.

hasen j
Norman's answer is good on the benefits of C in general, but you're exactly right that you'd be reimplementing the features even if you used C++.
Chuck
+2  A: 

Lua also has many features that are very easy to implement in Lisp, so why doesn't it take that as a basis? The point is that C is little more than glorified assembler code with only a thin layer of abstraction. It is like a somewhat polished blank slate, on which you can build your higher level abstractions. C++ is such a building. Lua is a different building, and if it had to use C++ abstractions, it would have to bend its intent around the existing C++ structure. Starting from the blank slate instead gives you the freedom to build it like you want.

Svante
Very nicely put.. though history show that quite often C++ is bent to things unimaginable. Who knows..
rama-jka toti
A: 

Just a side note, you should look into CLR (Rotor-incarnation) and Java sources and you will note it is far more C++-as-C rather than modern or good C++. So it has a parallel there and it is a side-effect of abstracting for toys and making it average-performance happy for the crowd in managed languages.

It also helps avoid pitfalls of naive C++ usage. Exceptions and all other sort of things (bits David at boost consulting kicked off and more while we build sequencers and audio sampling before he even had a job :) are an issue too..

Python integration is another matter, and has a messy history in boost for example.. But for primitive data types and interfaces/interop and machine abstraction, well it is quite clear nothing beats C. No compiler issues either, and it still bootstraps many things before you get to anything as influential as it is/was/will be.

Stepanov recognised this achievement when he nailed STL, and Bjarne nailed it with templates.. Those are the three things always worth thinking about, as you don't have a decent incarnation of them in popular managed languages, not to that expressivness and power. All of that more than 20 years later, which is remarkable and all still bootstrap via C/C++.. Legacy of goodness (but I'm not defending 'dark age' C code c1982-2000, just the idea, yuo can misuse anything ).

rama-jka toti