Related
I want to write a library that is dynamically loadable and callable from C code, but I really don't want to write it in C - the code is security critical, so I want a language that makes it easier to have confidence that my code is correct. What are my options?
To be more specific, I want C programmers to be able to #include this, and -l that, and start using my library just as if I had written it in C. I'd like programmers in other languages to be able to use their favourite tools for linking to C libraries to link to it. Ideally I'd like that to be possible on every platform that supports C, but I'll settle for Linux, Windows and MacOS.
Anything that compiles to native code. So you might Google for that - "languages that compile to native code." See, e.g., Programming languages that compile to native code and have the batteries included
C++ is often the choice for this. Compiles to native code and provided you keep your interfaces simple, easy to write an adapter layer.
Objective C and Fortran are also possible.
It sounds like you are looking for a language with ABI compatibility or which can be described as resulting in native code. So long as it can be compiled to a valid object file (typically an .obj or .o file) which is accepted by the linker, that should be the main criteria. You also then want to write a header file as a convenience for any client code which is written in C (or a closely related language/variant thereof).
As mentioned by others, you need a pretty good reason for choosing a language other than C as it is the lingua-franco of low-level/systems software. Assembler is an option, although harder to port between platforms. D is a more portable - but less widespread - alternative which is designed to produce secure, efficient native code with a minimum of fuss. There are many others.
Almost every security critical application I know of is written in C. I don't believe that there are any other language that has higher real status in producing secure applications.
C is being said to be a poor language for security by people who don't understand.
If you want C programmers to use your library, use C. Doing anything else is tying one hand behind your back whilst trying to walk on a balance beam (the gymnastics equipment). Sure, there are dozens of other languages that are CAPABLE of interfacing to C, but it typically involves using a C layer and then stuffing the C data types into a language specific data type (Java Objects, Python Objects, etc, etc), and when the call is finished, you use the same conversion back to a C data type. Just makes it harder to work with, and potentially slower if you don't get all the design decisions right. And people won't understand the source code, so won't like to use it (see more about this below).
If you want security, then write very good code, wearing your "security aspects" hat firmly on at all times, find a security mailing list or website and post it there for review, take the review comments on board, understand the comments, and fix any comments that are meaningful to fix. Distribute the source code to the users, so people can see what your code does. Those that understand security will know what to look for and understand that you have done a good job (or a bad job, whichever is applicable) - and those who don't will hopefully trust the right pople. If it's good, people will use it. If it's "hidden", and not easy to access, you won't get many customers, no matter what language you use.
Don't worry, you won't reveal anything more from releasing source. If there is a flaw in the code, and it is popular (or important) enough, someone will find the flaw, even if you publish only binaries. For those skilled in reverse engineering, not having source code is only a small obstacle.
Security doesn't stem from using a specific language or a specific tool, it stems from good design and good basic understanding of the problems with security.
And remember security by obscurity (whether that means "hidden source code" or "unusual language" or something else obscure) is false security.
You might be interested in ATS, http://ats-lang.sourceforge.net/. ATS compiles via C, can be as efficient as C, and can be used in a way that is ABI-compatible with C. From the project website:
ATS is a statically typed programming language that unifies implementation with formal specification. It is equipped with a highly expressive type system rooted in the framework Applied Type System, which gives the language its name. In particular, both dependent types and linear types are available in ATS. The current implementation of ATS (ATS/Anairiats) is written in ATS itself. It can be as efficient as C/C++ (see The Computer Language Benchmarks Game for concrete evidence) and supports a variety of programming paradigms
ATS's dependent and linear type system helps produce static guarantees about your code, including various aspects of resource management safety.
Chris Double has been writing a series of articles exploring the power of ATS's type system for systems programming here: http://bluishcoder.co.nz/tags/ats/. Of particular note is this article: http://bluishcoder.co.nz/2012/08/30/safer-handling-of-c-memory-in-ats.html
This document covers aspects of calling back and forth between ATS and C code: https://docs.google.com/document/d/1W6DYQApEqKgyBzMbvpCI87DBfLdNAQ3E60u1hUiMoU0
The main downside is that dependently-typed programming is still a daunting prospect, even for non-systems programming. The syntax of the language is also a bit weird: consider lexical quirks such as the use of abst#ype as a keyword. Finally, ATS is to some degree a research project, and I personally don't know whether it would be sensible to adopt for a commercial endeavour.
Theoretically, it's going to be Fortran: less indirection (as in: my array is [here], not just a pointer to here, and this is true of most but not all of your data structures and variables).
However... There are many gotchas and quirks in Fortran: not, perhaps, as many as in C but you probably know your way around C rather better than Fortran. Which is the point behind most of the comments saying 'Know your code' - but do you really know what your compiler is doing?
Knowing you, I'm prepared to take it on trust that you do, for C. Most programers don't. You do not know and cannot know what a local JVM or JIT compiler does, and that's a black hole in your security model if you're using Java or C# r scripting languages.
Ignore anyone who tells you that the hairy-chested he-men of secure computing write their own assembler: they probably don't even know the security errors they're making in any and all nontrivial projects they release. Know your compiler, indeed.
You could write it in lua - providing a C API to a Lua library is relatively straight forward. C++ is also an option, though of course you'd have to write C wrappers and make sure no exceptions can escape your functions. But honestly, if it's security critical the minor inconveniences of the C language shouldn't be that much of a big deal. What you really should be doing is prove the correctness of your program where feasible, and test extensively where it's not.
You can write a library in Java. JNI is normally used to call C from Java, but it can be used the other way around.
There is finally a decent answer to this question: Rust.
I came across this: Writing a compiler using Turbo Pascal
I am curious if there are any tutorials or references explaining how to go about creating a simple C compiler. I mean, it is enough if it gets me to the level of making it understand arithmetic operations. I became really curious after reading this article by Ken Thompson. The idea of writing something that understands itself seems exciting.
Why did I put up this question instead of asking Google? I tried Google and the Pascal one was the first link. The rest did no seem relevant and added to that... I am not a CS major (so I still need to learn what all those tools like yacc do) and I want to learn this by doing and am hoping people with more experience are always better at these things than Google. I want to read some article written in the same spirit as the one I listed above but that which highlights at least the bootstrapping phases of building a simple C compiler.
Also, I don't know the best way to learn. Do I start off building a C compiler in C or some other language? Do I write a C compiler or some other language? I feel questions like this are better answered once I have some direction to explore. Any suggestions?
Any suggestions?
A compiler consists of three pieces:
A parser
An abstract syntax tree (AST)
An assembly code generator
There are lots of nice parser generators that start with language grammars. Maybe ANTLR would be a good place for you to start. If you want to stick to C roots, try lex/yacc or bison.
There are grammars for C, but I think C in its entirety is complex. You'd do well to start off with a subset of the language and work your way up.
Once you have an AST, you use it to generate the machine code that you'll run.
It's doable, but not trivial.
I'd also check Amazon for books about writing compilers. The Dragon Book is the classic, but there are more modern ones available.
UPDATE: There have been similar questions on Stack overflow, like this one. Check out those resources as well.
I advise you this tutorial:
LLVM tutorial
It is a small example on how to implement a "small language" compiler. The source code is very small and is explained step by step.
There is also the C front end library for the LLVM (Low Level Virtual Machine which represent the internal structure of a program) library:
Clang
For what it's worth, the Tiny C Compiler is a pretty full-featured C compiler in a relatively small source package. You might benefit from studying that source, as it's probably significantly easier to understand than trying to comprehend all of GCC's source base, for instance.
This is my opinion (and conjecture) it will be hard to write a compiler without understanding data structures normally covered in undergraduate (post secondary) Computer Science classes. This doesn't mean you cannot, but you will need to know essential data structures such as linked lists, and trees.
Rather than writing a full or standards compliant C language compiler (at least in the start), I would suggest limiting yourself to a basic subset of the language, such as common operators, integer only support, and basic functions and pointers. One classic example of this was Ron Cain's Small-C, made popular by a series of articles written in Dr. Dobbs Journal in I believe the 1980s. They publish a CD with the James Hendrix's out-of-print book, A Small-C Compiler.
What I would suggest is following Crenshaw's tutorial, but write it for a C-like language compiler, and whatever CPU target (Crenshaw targets the Motorola 68000 CPU) you wish to target. In order to do this, you will need to know basic assembly of which ever target you want to run the compiled programs on. This could include a emulator for a 68000, or MIPS which are arguably nicer assembly instruction sets than the venerable CISC instruction set of the Intel x86 (16/32-bit).
There are many potential books that can be used as starting points for learning compiler / translator theory (and practice). Read the comp.compilers FAQ, and reviews at various online book sellers. Most introductory books are written as textbooks for sophomore to senior level undergraduate Computer Science classes, so they can be slow reading without a CS background. One older book that might be more introductory, but easier to read than "The Dragon Book" is Introduction to Compiler Construction by Thomas Parsons. It is older, so you should be able to find an used copy from your choice of online book sellers at a reasonable price.
So I'd say, try starting with Jack Crenshaw's Let's Build a Compiler tutorial, write your own, following his examples as a guide, and build the basics of a simple compiler. Once you have that working, you can better decide where you wish to take it from that point.
Added:
In regards to the bootstrapping process. Since there are existing C compilers freely available, you do not need to worry about bootstrapping. Write your compiler with separate, existing tools (GCC, Visual C++ Express, Mingw / djgpp, tcc), and you can worry about self-compiling your project at a much later stage. I was surprised by this part of the question until I realized you were brought to the idea of writing your own compiler by reading Ken Thomas' ACM Turing award speech, Reflections on Trusting Trust, which does go into the compiler bootstrapping process. It's a moderated advanced topic, and is also simply a lot of hassle as well. I find even bootstrapping the GCC C compiler under older Unix systems (Digital OSF/1 on the 64-bit Alpha) that included a C compiler a slow and time consuming, error prone process.
The other sort-of question was what a compiler tool like Yacc actually does. Yacc (Yet Another Compiler Compiler or Bison from GNU) is a tool designed to make writing a compiler (or translator) parser easier. Based on the formal grammar for your target language that you input to yacc, it generates a parser, which is one portion of a compiler's overall design. Next is Lex (or flex from GNU) which used to generate a lexical analyzer or scanner, which is often used in combination with the yacc generated parser to form the skeleton of the front-end of a compiler. These tools make writer a front end arguably easier than writing an lexical analyzer and parser yourself. Crenshaw's tutorial does not use these tools, and you don't need to either, many compiler writers don't always use them. Of course Crenshaw admits the tutorial's parser is quite basic.
Crenshaw's tutorial also skips generating an AST (abstract syntax tree), which simplifies but also limits the tutorial compiler. It lacks most if not all optimization, and is very tied to the specific programming language and the particular assembly language emitted by the "back-end" of the compiler. Normally the AST is a middle piece where some optimization can be performed, and serves to de-couple the compiler front-end and back-end in design. For a beginner without a Computer Science background, I'd suggest not worrying about not having an AST for your first compiler (or at least the first version of it). I think keeping it small and simple will help you finish writing a compiler, in its first version, and you can decide from there how you want to proceed then.
You might be interested in the book/course The Elements of Computing Systems:Building a Modern Computer from First Principles.
Note that this isn't about building a "pc" from stuff you bought off newegg. It begins with a description of Boolean logic fundamentals, and builds a virtual computer from the lowest levels of abstraction to progressively higher levels of abstraction. The course materials are all online, and the book itself is fairly inexpensive from Amazon.
In the course, in addition to "building the hardware", you'll also implement an assembler, virtual machine, compiler, and rudimentary OS, in a step-wise fashion. I think this would give you enough of a background to delve deeper into the subject area with some of the more commonly recommended resources listed in the other answers.
In The Unix Programming Environment, Kernighan and Pike walk through 5 iterations of making a calculator working from simple C based lexical analysis and immediate execution to yacc/lex parsing and code generation for an abstract machine. Because they write so wonderfully I can't suggest smoother introduction. It is certainly smaller than C, but that is likely to your advantage.
How do I [start writing] a simple C compiler?
There's nothing simple about compiling C. The best simple C compiler is lcc by Chris Fraser and David Hanson. They spent 10 years working on the design to make it as simple as they possibly could, while still generating reasonably good code. If you have access to a university library, you should be able to get their book.
Do I start off building a C compiler in C or some other language?
Some other language. One time I got to ask Hanson what lessons he and Fraser had learned by spending 10 years on the lcc project. The main thing Hanson said was
C is a lousy language to write a compiler in.
You're better off using Haskell or some dialect of ML. Both languages offer functions over algebraic data types, which is a perfect match to the problems faced by the compiler writer. If you still want to pursue C, you could start with George Necula's CIL, which is a big chunk of a C compiler written in ML.
I want to read some article written in the same spirit as the one I listed above but that which highlights at least the bootstrapping phases...
You won't find another article like Ken's. But Andrew Appel has written a nice article called Axiomatic Bootstrapping: A Guide for Compiler Hackers I couldn't find a free version but many people have access to the ACM Digital Library.
Any suggestions?
If you want to write a compiler,
Use Haskell or ML as your implementation language.
For your first compiler, pick a very simple language like Oberon or like P0 from Niklaus Wirth's book Algorithms + Data Structures = Programs. Wirth is famous for designing languages that are easy to compile.
You can write a C compiler for your second compiler.
A compiler is a complex subject matter that covers aspects of
Input processing involving Lexing, Parsing
Building a symbol store of every variable used such as an Abstract Syntax Tree (AST)
From the AST tree, transpose and build a machine code binary based on the syntax
This is by no means exhaustive as it is an abstract bird's eye view from the top of a mountain, it boils down to getting the syntax notation correct and ensuring that malformed inputs do not throw it off, in fact a good input processing should never fall on its knees no matter how malformed, terrible, abused cases of input that gets thrown at it. And, also in deciding and knowing what output is going to be, is it in machine code, which would imply you may have to get to know the processor instructions intimately...including memory addressing for variables and so on...
Here are some links for you to get started:
There was a Jack Crenshaw's port of his code for C....(I recall downloading it months ago...)
Here's a link to a similar question here on SO.
Also, here's another small compiler tutorial for Basic to x86 assembler compiler.
Tiny C Compiler
Hendrix's Small C Compiler found here.
It might be worthwhile to learn about functional programming, too. Functional languages are well-suited to writing a compiler both in and for. My school's intro compilers class contained an intro to functional languages and the assignments were all in OCaml.
Funny you should ask this today, since just a couple days ago I wrote a lambda calculus interpreter. Lambda calculus is the granddaddy of all functional languages. It's just 200 lines long (in C++, incl. error reporting, some pretty printing, some unicode) and has a two-phase structure, with an intermediate format that could be used to generate code.
Not only is starting small and building up the most practical approach to compilers, it also encourages good, modular, organizational practice.
A compiler is a very large project, although I suppose it wouldn't hurt to try.
I know of at least one C compiler written in Pascal, so it's not the most insane thing you could do. I personally would pick a more modern language in which to implement my C compiler project, both for the simplicity (it's easy to d/l packages for Python, Ruby, C, C++ or Java) and because it will look better on your resume.
In order to do a compiler as a beginner project, though, you will need to drink all of the Agile kool-aid.
Always have something running, even if it doesn't do much of anything. Add things to your compiler only in small steps. ("Frequent releases".) Pick a viciously tiny subset of the language and implement that first. (Support only i = 0; at first and expand things from there.)
If you want a mind-blowing experience that teaches you how to write compilers that compile themselves, you need to read this paper from 1964.
META II a syntax-oriented compiler writing language by Val Schorre.
In 10 pages, it tells you how to write compilers, how to write meta compilers, provides a virtual metacompiler instruction set, and a sample compiler built with the metacompiler.
I learned how to write compilers from this paper back in the late 60s, and used the ideas to construct C-like langauges for several minicomputers and microprocessors.
If the paper is too much by itself (it isn't!) there's an online tutorial which will walk you through the whole thing.
And if getting the paper from the original link is awkward because you are not an ACM member, you'll find that the tutorial contains all the details anyway. (IMHO, for the price, the paper itself is waaaaay worth it).
10 pages!
I would not recommend starting with C as the language to implement, nor with any of the compiler-generator or parser-generator tools. C is a very tricky language, and it's probably a better idea to just make up a language of your own. It can be a little C-like (e.g. use curly backets if you want to indicate the function body, use the same type names, so you don't have to remember what you called everything).
The tools for making compilers and parsers are great, but have the problem of really being a shorthand notation. If you don't know how to create a compiler in longhand, the shorthand will seem cryptic, needlessly restrictive etc. So write your own simple compiler first, then continue on from there. I also recommend you don't start generating actual machine code unless you eat and breathe assembler. Create your own bytecode interpreter with a VM.
As to what language you should use to create your first compiler: It doesn't really matter, as long as the language is fairly complete. You will be reading input text, building data structures from them and writing out binary data. So if a language makes those things easier in any way, that's a point in favor of it. Pick a language you know well, so you can focus on creating the compiler, not learning the language. I usually use an OO language, which makes the syntax tree easier to write, a functional language would probably also work if you are familiar with that.
I've blogged a lot about programming languages, so you might find some useful postings here: http://orangejuiceliberationfront.com/category/language-design/
In particular, http://orangejuiceliberationfront.com/how-to-write-a-compiler/ is a starter on the particulars of parsing common constructs and generating something useful from that, as well as http://orangejuiceliberationfront.com/generating-machine-code-at-runtime/ which talks about actually spitting out Intel instructions that do something.
Oh, regarding bootstrapping of a compiler: You probably won't be able to do that right from the start. There is a fair amount of work involved in creating a compiler. So not only would writing a bootstrapping compiler involve writing the compiler (in some other language), once you have it, you would then have to write a second version of the compiler using itself. That's twice the work, plus the debugging needed in the existing and the bootstrapped new compiler until it all works. That said, once you have a working compiler, it is a good way to test its completeness. OK, maybe not twice the work, but more work. I'd go for the easy successes first, then move on from there.
In any event, have fun!
This is not meant to be inflammatory or anything like that, but I am in the midst of learning C, and (think) I have a good handle on most of the basics. I've done all of the various book exercises: primes generators, Fibonacci generators, string manipulation, yadda yadda, but none of this is cool.
What is the "bridge" between command line programs and something -cool-? I've heard of various games being written in C, but how?
Forgive my exasperation, but it feels like I've been learning lots but can still only do relatively little. Thanks for any insight on what to do with C.
Relevant information: OS X leopard, PHP and web development experience (which is so great because projects are immediately in a context where you recognize how they can be powerful)
C is the concrete and the steel of modern tech
There was a time when almost everything was written in C, or in something much worse.
These days, many of the advanced languages and systems are actually implemented in C or C++, and then those things implement more systems. It is standing on the shoulders of giants, as the expression goes. Almost every OS kernel, browser, and heavy-duty-web-server is written in C/C++.
So sure, you don't see the steel in the high rise, you see the beautiful interior furnishings and the sleek glass windows. You don't want a steel or concrete desk, and if you did, it would be too expensive to build for you.
Back to your GUI question: your first C graphics program should probably use the original X Window System directly. Don't spend too much time there, but then move on to one of the more advanced Widget toolkits such as GTK+ or (the C++) Qt. Be sure to investigate your OS X system, as it has one of the most advanced of them all.
I try love to write things in Ruby these days, but I happen to know there are over 100,000 200,000 lines of C code implementing that cool Ruby language system. :-)
Summary
Ok, this post got really big, so here's a quick summary before you read it: to program GUIs, there are a number of good C/C++ libraries (for example, QT). What most people do, on Windows systems at least, is to use a .NET language (like C#) when they want GUIs, and C/C++ when they want more control/speed. It's also very common to use both in combination, i.e. make a GUI in C# and speed-critical parts in C.
I still encourage you to read the longer answer, it contains a lot more information on your options.
Longer answer
I'll start with the big question, then answer (as best I can) your specific question about creating a GUI. I think you're kind of suffering from the fact that C is used to teach programming, and it's much easier to do so only using command line programs (after all, they're much simpler to write). This doesn't mean that C can't do all of the stuff you want, like GUIs specifically. It does. I don't think there's any type of software that hasn't been done in C, usually before it was done in other languages.
All right, some answers:
Is C Useful?
C, and its very close relative C++, are responsible for a huge portion of the world's code. I don't know if more code is written in C than any other language, but I'm guessing it's not far off.
Most of the really important programs you use are actually written in C/C++. Just for one example, Windows.
Where is C used today?
C/C++ are still used a lot. They're especially useful for developing low-level stuff (i.e. stuff like Operating Systems, which need a lot of speed, a lot of ability to control exactly what your code does, etc.).
But don't think it's all low level for C programmers. Even today, with many other languages available (which are arguably much better, and certainly much easier to program), C is still used to create practically everything. GUI applications, which you specifically asked about, are very often made with C, even though nowadays, lots of people are switching to other languages. Note I say switching: C used to be the standard language for writing, well, everything, really.
How do I develop GUIs with C
Alright, you specifically wanted to know how to create a GUI with C (I'm hoping C++ is ok too).
First of all, it depends on a number of factors:
What Operating System are you writing for? (Windows, Mac, and Linux are the most common).
Do you want the GUI to work on other systems as well?
The most common case is writing software to work on Windows. In that case, the "natural" solution is to write things that work with the Win32 API. That's basically the library that "comes" with Windows, letting you do any GUI work you want to do.
The big problem with this is, it's kinda hard. As in, a lot hard. This is the reason most people don't do that kind of work anymore.
So what are your other options?
The most natural is going with what's called a .NET language. Those are a bunch of languages, together with libraries, that Microsoft created. They're probably the easiest way to get a GUI on Windows. The problem is, you can't really use them from C (since it's not a .NET language).
Assuming you want to stay in C/C++ land, you can use some kind of library which makes working with the Windows API easier (since it hides all the ugly details):
One of the most common is what's called MFC (Microsoft Foundation Classes), which are a bunch of C++ classes which make it "easier" to create Windows stuff. Unfortunately, this library is very old, and is really not that easy to use.
The other way to go if you want to program in C++ is to use some kind of third-party library. This is a library that someone other than Microsoft created, which makes it easier to create a GUI.
Another option is to create only the GUI part of your software in a .NET language, and use C/C++ for the other parts (or use the .NET language to do almost everything, and use C/C++ only when you really need it, for example when you need things to go really fast). This is a very popular option.
The advantage of a third party library is that, if you pick the right one, you can use the same code to create a GUI for all the Operating Systems at the same time.
I think the most famous of these libraries is QT, and also WxWidgets, but there are a bunch of other ones. I would personally pick QT since it seems to get the most fame, but I haven't worked with either.
Every major operating system has all of its low-level libraries implemented in C. Mac OS X is a Unix-like system under the hood, which is a wonderful world if you're a C programmer.
Check out The Art of Unix Programming for some great ideas.
As for GUI stuff, you'll probably want to use X11. There is plenty of good documentation out there -- most Unix programming stuff and most deep system-level stuff just assumes you're working in C, since that's what everybody uses for it.
Well, that depends. If you want to build desktop applications, a multiplatform GUI library whose main language is C is GTK+:
http://www.gtk.org/
For games, check out SDL:
http://www.libsdl.org/
Which provides you with thinks like direct input from keyboard, 2D graphics, some audio and even threads and stuff like that. It can also open an OpenGL context if you want to get into the 3D world (however it's hard to do it in raw OpenGl). Did I mention that SDL is multiplatform?
However the real strength of C is in systems programming. For desktop applications/games maybe you are best suited with C++. Now that you have command of C, learning the basic C++ should be easy ;).
Cool stuff do with C?
Operating Systems, device drivers, and python modules for starters.
Games typically will use C++ if they're C-Based, in my experience / what I've seen.
There are many libraries for C under Unix, such as X lib, which accesses X11.
If you wanted to get into robotics you may find C to be very useful, as you will have to write low-level code with very small memory footprints, so even C++ may not be the best choice.
C and C++ are very good at writing small, fast code, but OOP is not always the best choice, so at times you will find that C is a better choice, for example if you are writing a compiler or OS.
Sure there are some impressive programs made in C !
GNOME for example, arguably the most used desktop environment used in modern unix systems is written in C (the major parts at least) and is mostly based on GTK+ gui toolkit, itself done in C.
For game, OpenGL is a C api and is the standard for 3D graphic programming in multi-platform development (not uniquely microsoft platform), and Quake 3, which the engine, Id Tech 3, is available in GPL, is also writen in C. There also is many 2D games written using SDL library.
SDL is a good library for graphics and sound, and I've seen some cool stuff done with it. If you do it in C, it'll take longer to make, but from a performance point of view, it'll be much better.
If your idea of cool is GUI apps and you want to write native GUI apps on the Mac, you'll want to look at
Carbon. This is the official C API into the Mac GUI and OS. They keep threatening to kill it, but it survives.
Personally I think GUI apps are a very narrow definition of cool. What I think is cool is implementing parallelized math algorithms using opencl.
GTK-server is REALLY easy to get started with, in C or any other language. Just click that link.
For a "cool" application that goes beyond simple GUI's, check out the OpenCV computer vision library. It provides fast real-time image processing and face recognition.
Now you can access a webcam and start writing real-time computer vision games. For applications like these that are processor intensive, C is the ideal choice.
Last I checked more Open Source projects are started in C than in any other language.
The fact that C is used by so many large and successful projects doesn't particularly make it "good". The reason C is so commonly used is because of a few factors, it's been around a long time, it's fast, it lets you access both low level and high level interfaces as needed, and it's better than the other old languages (FORTRAN etc). The "cool" thing about C is that you can make it do absolutely anything: inject itself into the kernel and add some new features or bug fixes that you couldn't convince Microsoft to do, etc.
Yes, C can be and is easily used for things beyond the command line, but it's extremely dangerous due to pointers... Not to mention development in other more modern languages is faster (and safer) by magnitudes. I never use C unless it's the last resort, ie: need to implement something low level or needs that extra performance.
By the way, when I say C, I really mean C++. I'd never choose C over C++ unless I was forced to.
I've been working on a C program which does quite a lot of string manipulation, and very often needs to be tweaked and recompiled for some sort of special case processing. I've been thinking that embedding some scripting language with good string manipulation support might make sense for the project.
What language would provide the best string manipulation support while being easy to embed in a C program?
For some extra background...
Performance is pretty important (especially startup time)
Needs easily be compiled on multiple platforms (Linux, Solaris, Win32 (ideally with MinGW), Darwin)
Needs to be a language which will still be around in 5 years time
I've looked a little at Python (perhaps too heavy weight?) and Lua (perhaps not focused on string manipulation?) but don't really know enough about them or what other choices might be out there.
I've never regretted using Lua.
It's very easy to embed in your application. In fact, now I usually don't write C applications, i just write C libraries and control them from Lua.
Text manipulation isn't its best feature, but it's certainly far better than C alone. And the LPEG library makes building parsers almost trivially easy, putting any regex to shame (but still has a couple of regex-like syntaxes if you prefer them).
Lua stands head and shoulders above other choices.
... best string manipulation support while being easy to embed?
Lua is designed to be embedded in C; the API is clear and easy to use; the documentation is terrific.
Some other responses have denigrated Lua's string capabilities. I think they're underestimating Lua.
Lua's string capabilities actually find a sweet spot between "just concatenation" and the full complexity of regular expressions. String formatting capability is very strong, and accumulating strings through "buffers" or tables is simple and efficient.
String scanning is, in my opinion, one of the best parts of the design. It doesn't have "or" patterns but otherwise gives you a large fraction of what you get from regular expressions, including a very powerful and elegant "capture" function. For example, I can convert a string to hex by capturing every single character and applying a function to it:
s:gsub('.', function(c) return string.format("%02x", string.byte(c)) end)
Or I can escape non-alphanumeric, non-space characters into octal:
s:gsub('[^%w%s]', function(c) return string.format([[\%03o]], string.byte(c)) end)
Some of the features on display here:
The escape character for string scanning is %, which is different from the escape character for string quoting, which is \. This decision is brilliant and should win an award by itself :-)
There are multiple mechanisms for quoting literal strings, including [[...]] in which no characters have to be escaped. If you want to generate or match strings with backslashes in them (like LaTeX for example), this is a godsend.
If you want the full power of a context-free parser, you can always use LPEG, a library written by one of Lua's designers.
Performance is pretty important (especially startup time)
Lua consistently wins performance awards. Startup is lightning fast: the whole system (including compiler, library, garbage collector, and runtime system) fits in 150KB. To avoid pause times, Lua provides incremental garbage collection. See also SO question Why is Lua faster than other scripting languages?
You can make startup even faster by precompiling your scripts, but I've never found it necessary to do this—and because compiled code (as opposed to source code) is not portable, precompilation usually creates more headache than it solves.
Needs easily be compiled on multiple platforms
Lua compiles using pure ANSI C and does not even require POSIX. I have a version running on my PalmOS PDA.
Needs to be a language which will still be around in 5 years time.
Lua has been around since 1993. Moreover, the two members of the team who provide the most support are tenured professors at PUC-Rio. Lua is their livelihood. Finally, the whole system is only 17,000 lines of code. If Rio fell off the map tomorrow, anybody with a good undergraduate compiler course could pick the system up and maintain it. There would be plenty of volunteers.
I've looked a little at Python and Lua but don't really know enough about them
See SO question Which game scripting language is better to use: Lua or Python?.
People have been embedding tcl in larger projects for what seems like ages. It's been a while since I've had to use tcl for anything...
One of the things that sets tcl apart from other programming languages is that everything is a string.
And for your reference, here's the tcl documentation on string functions.
tcl might be easier to embed than perl, but I do have to agree #Matthew Scharley's reasoning. Also, tcl isn't exactly known for it's performance, but maybe that's changed in recent years.
Anyway, here is the tcl wiki link on embedding tcl in C applications, and a relevant quote from the page:
"How do I embed a Tcl interpreter in my existing C (or C++) application?" is a very frequently-asked question. It's straightforward, certainly far easier than doing the same with Perl or, in general, Python; moreover, this sort of "embeddability" was one of the original goals for Tcl, and many, many projects do it. There are no complete discussions of the topic available, but we can give an overview here. (RWT 14-Oct-2002)
Another alternative might be to go with Lua, as you mentioned, while extending it with another C string library of your choice (Google turns up The Better String Library, for instance).
Once you've compiled Lua into your application, you can "extend" C functions to Lua's interpreter. Or maybe the built-in string functions are adequate for you.
You certainly have a few options.
We looked at both Python and Lua for scripting for a .NET product. The goal was to provide some scripability for end users. The decision came down to Python because the powers-that-be preferred anything with Microsoft support to everything else. My choice was for Lua.
There's a good survey paper on the relative merits of the embedding APIs of various scripting languages:
H. Muhammad and R. Ierusalimschy. C APIs in extension
and extensible languages. Journal of Universal Computer
Science, 13(6):839–853, 2007.
Looking at combining both excellent string manipulation and an excellent embed API, I would suggest, in order:
Ruby: Excellent string support, including syntax support for regex. Well-designed embed API, very easy to use.
Lua: I'm not sure how its string support is, but its supposed to be a great language for embedding.
Python: Less easy to embed, slightly harder to use string features than Ruby. But it has Pyrex, so that might be an easier way to embed it.
PHP: Nasty API, nasty language. The embed SAPI is really a second-class citizen, but it does work. There are a lot of string manipulation functions. Still, I wouldn't recommend it.
Perl: Nasty to embed (so far as I've heard), string support could be better.
I can't comment about TCL, but I hear its designed for embedding.
Python is not heavyweight at all! It's quite simple to embed (here's the official guide, but you can find many tutorials as well), very powerful, great for string processing, and a pleasant and easy language to use overall. It has a huge user community and support base, which is a bonus.
Python has also been embedded into a large number of real-life applications. One cool example I can think of immediately is the Civilization IV game, most of which runs on Python scripts on top of a C++ API.
Some people may disagree but Sara Goleman has published a great book on extending and embedding PHP. Which is becoming one of the most widely used languages around... :)
PHP String support isn't as great as say Perl, but it's very usable.
Did I mention it's written in C?
</my2cents>
Perl. Its (original) reason for being is string manipulation.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Joel and company expound on the virtues of learning C and how the best way to learn a language is to actually write programs using that use it. To that effect, which types of applications are most suitable to the C programming language?
Edit:
I am looking for what C is good at. This likely does not coincide with the best way of learning C.
Code where you need absolute control over memory management. Code where you need to be utterly in control of speed versus memory trade-offs. Very low-level file manipulation (such as access to the raw devices).
Examples include OS kernel, and embedded apps.
In the late 1980s, I was head of the maintenance team on a C system that was more than a million lines of code. It did database access (Oracle), X Windows graphics, interprocess communications, all sorts of good stuff. It ran on VMS and several varieties of Unix. But if I were to recreate that system today, I sure wouldn't use C, I'd use Java. Others would probably use C#.
Low level functions such as OS kernel and drivers. For those, C is unbeatable.
You can use C to write anything. It is a very general purpose language. After doing so for a little while you will understand why there are other "higher level" languages available.
"Learn C", by all means, but don't don't stick with it for too long. Other languages are far more productive.
I think the gist of the people who say you need to learn C is so that you understand the relationship between high level code and the machine internals and what exaclty happens with bits, bytes, program execution, etc.
Learn that, and then move on.
Those 100 lines of python code that were accounting for 80% of your execution time.
Small apps that don't have a UI, especially when you're trying to learn.
Edit: After thinking a little more on this, I'd add the following: if you already know a higher-level language and you're trying to learn more about C, a good route may be to not create a whole new C app, but instead create a C DLL and add functions to it that you can call from the higher language. In this way you can replace simple functions that your high language already has to ensure that you C function does what it should (gives you pre-built testing), lets you code mostly in what you're familiar with, uses the language in a problem you're already familiar with, and teaches you about interop.
Anything where you think of using assembly.
Number crunching (for example, libraries to be used at a higher level from some other language like Python).
Embedded systems programming.
A lot of people are saying OS kernel and device drivers which are, of course, good applications for C. But C is also useful for writing any performance critical applications that need to use every bit of performance the hardware is capable of.
I'm thinking of applications like database management systems (mySQL, Oracle, SQL Server), web servers (apache, IIS), or even we browsers (look at the way chrome was written).
You can do so many optimizations in C that are just impossible in languages that run in virtual machines like Java or .NET. For instance, databases and servers support many simultaneous users and need to scale very well. A database may need to share data structures between multiple users (threads/processes), but do so in a way that efficiently uses CPU caches. In C, you can use an operating system call to determine the size of the cache, and then align a data structure appropriately to the cache line so that the line does not "ping pong" between caches when multiple threads access adjacent, but unrelated data (so called "false sharing). This is one example. There are many others.
A bootloader. Some assembly also required, which is actually very nice..
Where you feel the need for 100% control over your program.
This is often the case in lower layer OS stuff like device drivers,
or real embedded devices based on MCU:s etc etc (all this and other is already mentioned above)
But please note that C is a mature language that has been around for many years
and will be around for many more years,
it has many really good debugging tools and still a huge number off developers that use it.
(It probably has lost a lot to more trendy languages, but it is still huge)
All its strengths and weaknesses are well know, the language will probably not change any more.
So there are not much room for surprises...
This also means that it would probably be a good choice if you have a application with a long expected life cycle.
/Johan
Anything where you need a minimum of "magic" and need the computer to do exactly what you tell it to, no more and no less. Anything where you don't trust the "magic" of garbage collection to handle your memory because it might not be as efficient as what you can hand-code. Anything where you don't trust the "magic" of built-in arrays, strings, etc. not to waste too much space. Anything where you want to be able to reason about exactly what ASM instructions the compiler will emit for a given piece of code.
In other words, not too much in the real world. Most things would benefit more from higher level abstraction than from this kind of control. However, OS code, device drivers, and a few things that have to be near optimal in both space and speed might make sense to write in C. Higher level languages can do pretty well competing with C on speed, but not necessarily on space.
Embedded stuff, where memory-usage and cpu-speed matters.
The interrupt handler part of an OS (and maybe two or three more functions in it).
Even if some of you will now start to bash heavily on me now:
I dont think that any decent app should be written in C - it is way too error prone.
(and yes, I do know what I am talking about, having written an awful lot of code in C myself (OSes, compilers, VMs, network protocols, RT-control stuff etc.).
Using a high level language makes you so much more productive. Speed is typically gained by keeping the 10-90 rule in mind: 90% of CPU time is spent in 10% of your code (which you should optimize first).
Also, using the right algorithm might give more performance than optimizing bits in C. And doing things right in C is so much more trouble.
PS: I do really mean what I wrote in the second sentence above; you can write a complete high performance OS in a high level language like Lisp or Smalltalk, with only a few minor parts in C. Think how the 70's Lisp machines would fly on todays hardware...
Garbage collectors!
Also, simply programs whose primary job is to make operating-system calls. For example, I need to write a short C program called timeout that
Takes a command line as argument, with a number of seconds for that command to run
Forks two child processes, one to run the command and one to sleep for N seconds
When the first of the child processes exits, kills the other, then exits
The effect will be to run a command with a limit on wall-clock time.
I and others on this forum have tried several different solutions using shells and/or perl. All are convoluted and none quite do the right thing. In C the solution will be easy, because all the OS facilities are right where you can get at them.
A few kinds that I can think of:
Systems programming that directly uses Unix/Linux or Win32 system calls
Performance-critical code that doesn't have much string manipulation in it (e.g., number crunching)
Embedded programming or other applications that are severely resource-constrained
Basically, C gives you portable, efficient access to the native capabilities of the machine; everything else is your responsibility. In particular, string manipulation in C is tedious, error-prone, and generally nasty; the most effective way to do extensive string operations with C may be to use it to implement a language that handles strings better...
examples are: embedded apps, kernel code, drivers, raw sockets.
However if you find yourself more productive in C then go ahead and build whatever you wish. Use the language as a tool to get your problem solved.
c compiler
Researches in maths and physics. There are probably two alternatives: C and C++, but such features of the latter as encapsulation and inheritance are not very useful there. One could prefer to use C++ "as a better C" or just stay with C.
Well most people are suggesting system programming related things like OS Kernels , Device Drivers etc. These are difficult and Time consuming. Maybe the most fun thing to with C is console programming. Have you heard of the HAM SDK? It is a complete software development kit for the Nintendo GBA , and making games for it is fun. There is also the CC65 Compiler which supports NES Programming (Althought Not Completely). You can also make good Emulators. Trust Me , C is pretty helpful. I was originally a Python fan, and hated C because it was complex. But after yuoget used to it, you can do anything with C. Now I use CPython to embed Python in my C Programs(if needed) and code mostly in C.
C is also great for portability , There is a C Compiler for like every OS and Almost Every Console And Mobile Device. Ive even seen one that supports some calculators!
Well, if you want to learn C and have some fun at the same time, might I suggest obtaining NXC and a Lego Mindstorms set? NXC is a C compiler for the Lego Mindstorms.
Another advantage of this approach is that you can compare the effort to program the Mindstorms "brick" with C and then try LEJOS and see how it goes with Java.
All great fun.
Implicit in your question is the assumption that a 'high-level' language like Python or Perl (or Java or ...) is fast enough, small enough, ... enough for most applications. This is of course true for most apps and some choice X of language. Given that, your language of choice almost certainly has a foreign function interface (FFI). Since you're looking to learn C, create a module in the FFI built in C.
For example, let's assume that your tool of choice is Python. Reimplement a subset of Numpy in C. Since C is a pretty fast language, and has, in C99, a clear numeric library interface, you'll get the opportunity to experience the power of C in an appropriate setting.
ISAPI filters for Internet Information Server.
Before actually write C code, i would suggest first read good C code.
Choose subject you want to concentrate on, basically any application can be written in C, but i assume GUI application will be not your first choice, and find few open source projects to look into.
Not any open source project is best code to look. I assume that after you will select a subject there is a place for another question, ask for best open source project in the field.
Play with it, understand how it's working modify some functionality...
Best way to learn is learn from somebody good.
Photoshop plugin filters. Lots and lots of interesting graphical manipulation you can do with those and you'll need pure C to do it in.
For instance that's a gateway to fractal generation, fourier transforms, fuzzy algorithms etc etc. Really anything that can manipulate image/color data and give interesting results
Don't treat C as a beefed up assembler. I've done some serious app's in it when it was the natural language (e.g., the target machine was a Solaris box with X11).
Write something with some meat on it. Write a client server chess program, where the AI is on a server and the UI is displaying in X11; once you've done that you will really know C.
I wonder why nobody stated the obvious:
Web applications.
Any place where the underlying libraries are entirely in C is a good candidate for staying in C - openGL, Lua extensions, PHP extensions, old-school windows.h, etc.
I prefer C for anything like parsing, code generation - anything that doesn't need a lot of data structure (read OOP). It's library footprint is very light, because class libraries are non-existent. I realize I'm unusual in this, but just as lots of things are "considered harmful", I try to have/use as little data structure as possible.
Following on from what someone else said. C seems a good language to implement the language in which you write the rest of your software.
And (mutatis mutandis) the virtual machine which runs the rest of your software.
I'd say that with the minuscule runtime environment and it's self-contained nature, you might start by creating some CLI utilities such as grep or tail (or half the commands in Unix). Anything that uses only STDOUT, STDIN and file manipulation is a good candidate.
This isn't exactly answering your question because I wouldn't actually CHOOSE to use C in such an app, but I hope it's answering the question you meant to ask--"what would be a good type of app to use learn C on?"
C isn't actually that bad a language--it's pretty easily to understand your code at an assembly language level which is quite useful, and the language constructs are few, leaving a very sparse language.
To answer your actual question, the very best use of C is the one for which it was created--porting itself (and UNIX) to other CPU architectures. This explains the lack of language features very well; it also explains the existence of Pointers which are really just a construct to make the compiler work less--any code created with pointers could be created without it (just as well optimized), but it becomes much harder to create a compiler to do so.
digital signal processing, all Pure Data extensions are written in C, this can be done in other languages also but has had good success in C