96

I code a lot in both C and C++, but did not expect C to be the second most popular language, slightly behind Java.

TIOBE Programming Community Index

I'm curious as to why, in this age of OOP, C is still so popular? Note that 4 out of the top 5 popular programming languages are "modern", object-oriented capable languages.

Now, I agree that you can use OOP in C to some extent, but it's sort of painful and inelegant (well at least compared to C++ I guess). So, what makes C so popular? Is it efficiency; being low-level; the vast majority of libraries that already exist or something else?

15
  • 18
    videogames, embedded systems, hardware programming (firmware), operating systems, etc.
    – user49943
    Mar 24, 2012 at 11:42
  • 25
    Note that you only get what you measure - in the case of TIOBE, the number of hits for +"<language> programming" on popular search engines. A blog post "Why nobody does C programming anymore" counts for C in this index. Heck, even this question may does as soon as google picks it up.
    – user7043
    Mar 24, 2012 at 11:52
  • 40
    The age of OOP? that's a pretty bold statement. Mar 24, 2012 at 20:23
  • 57
    You have the illusion that OOP is a silver bullet, you should lose that quickly, there is nothing special or "good" about OOP, it's just one of many code organization strategies.
    – Raynos
    Mar 24, 2012 at 22:04
  • 23
    @DeadMG: Pot, meet kettle. TIOBE's data may not be reliable, but your bald assertion that "it's not popular" has no source or citation whatsoever. If you're going to challenge the assumption behind the question, at least provide some evidence to back it up. Mar 24, 2012 at 22:23

15 Answers 15

145

A few factors that contribute:

  • C is ubiquitous. Whatever the platform, C is probably available.
  • C is portable. Write a piece of clean C, and it compiles with minimal modifications on other platforms - sometimes it even works out-of-the-box.
  • C has been around for a while. Back in the days when UNIX conquered the world, C (the UNIX programming language of choice) shared in its world domination, and became the lingua franca of the programming world. Any serious programmer can be expected to at least make some sense of a chunk of C; the same can't be said about most other languages.
  • C is still the default language for UNIX and UNIX-flavored systems. If you want a library to succeed in open-source land, you need fairly good reasons not to use C. This is partially due to tradition, but more because C is the only language you can safely assume to be supported on any UNIX-like system. Writing your library in C means you can minimize dependencies.
  • C is simple. It lacks the expressivity of sophisticated OOP or functional languages, but its simplicity means it can be picked up quickly.
  • C is versatile. It is suitable for embedded systems, device drivers, OS kernels, small command-line utilities, large desktop applications, DBMS's, implementing other programming languages, and pretty much anything else you can think of.
  • C is fast. Most C implementations compile directly to machine code, and the programmer has full power over what happens at the machine level. There is no interpreter, no JIT compiler, no VM or runtime - just the code, a compiler, a linker, and the bare metal.
  • C is 'free' (in both the beer and the speech sense). There is no single company that owns and controls the standard, there are several implementations to choose from, there are no copyright, patenting or trademark issues for using C, and some of the best implementations are open-source.
  • C has a lot of momentum going. The language has been popular for decades, so there is an enormous amount of applications, libraries, tools, and most of all, communities, to support the language.
  • C is mature. The last standard that introduced big changes is C99, and it is mostly backwards-compatible with previous standards. Unlike newer languages (say, Python), you don't have to worry about breaking changes anytime soon.
  • C is compatible. Most languages have bindings to talk to C. This means one can develop a library in C using standard calling conventions, and feel confident that almost any other language can link against that library. To name a few popular languages in widespread use: C#, Java, Perl, Python, PHP can all link against C libraries without much trouble.
  • C is powerful: if the language cannot do something, all popular compilers allow embedding assembler code which can do anything the hardware can do. Transitively combined with the above point about compatibility, this means C can act as a liaison between higher level languages and the "bare metal" of assembly.
17
  • 9
    I think not all your arguments are correct. 1) C is ubiquitous. C++ is as ubiquitos as C, since there are C++ to C compilers. 2) C is portable. The same with C++. 3). C has been around for a while. The same with C++. 4). C is versatile. The same with C++. 5) C is fast. The same with C++. 6). C is 'free'. The same with C++. 7). C has a lot of momentum going. The same with C++ again. 8)C is mature. The same with C++. So you actually don't answer the question. Mar 24, 2012 at 19:25
  • 19
    C11 is the latest standard, not C99. Not that it really matters as everyone uses '89.
    – Pubby
    Mar 24, 2012 at 19:32
  • 56
    @KonstantinSolomatov: If you are writing a library that will be consumed by other people, please do the world a favor and write it in C instead of C++. If you can't do that, at least write a C API. Everything in the universe can link to C code in some way or another, usually with minimal effort. By contrast, you will frequently have major ABI issues when trying to call C++ code from other C++ code, let alone from other languages. Mar 24, 2012 at 20:43
  • 41
    @KonstantinSolomatov - the fact that there's a need for a C++ to C compiler kind of proves that C is the one that's ubiquitous.
    – detly
    Mar 25, 2012 at 7:58
  • 12
    @KonstantinSolomatov: Please stop thinking that C is C++. C does not have closures. Some extensions of C do (such as that implemented by the gcc family of compilers) but C itself does not (i.e., it's not in the original K&R spec or any of the finalized C standards). Mar 29, 2012 at 21:35
92
+50

I've always tended to blame the popularity of C on the need for a universal assembly language. It's combination of specificity at the machine level, standardization, and extreme portability allow C to function as that de facto universal assembly language, and for that reason I suspect its role there will continue indefinitely.

I should mention that I'm always a bit surprised when OOP is presented in programming courses as a sort of "final model" that is the only possible endpoint for good programming. Like many other aspects of programming, the value of OOP is a compromise between many competing factors, including how human brains organized information, how societal groups support software over the long term, and in the case of object-oriented programming, some pretty deep aspects of how the universe itself works.

And that last point is worth hammering a bit. Read further if you are interested in a physics-level exploration of why certain programming styles exist, how they work together, and where the world may be heading in the future as we expand further on such concepts...

An object in physics is anything that maintains recognizable coherence over time. That in turn allows simple creatures like ourselves to get away with representing the object using only a small number of bits, without endangering our survival too badly. But in terms of physics in the large, the number of things you have to get exactly right to make that kind of simplification easy and common is remarkably large. As humans we don't think about all of that much because quite frankly, we wouldn't be here if it were not true.

Sound too abstract? It really isn't. Imagine for example trying to navigate the road to your friend's house if instead of cars you encountered rapidly oscillating plasma fields and momentary condensations of matter moving with an enormous range of velocities. Such a scenario might cut rather deeply into socialization opportunities, yes? We need objects, we are objects, and the existence of objects provides us with an enormous and critically important level of simplification of the environment around us.

So let's pull all of that back around to software. What do objects in the real world have to say about objects in terms of programming?

Well, for one thing it means that what defines a "good" object in software should really be whether or not the type of data you are handling readily supports the idea of recognizable persistence over time.

With the definition, the easiest forms of OOP are easy to recognized. They are the ones that cop out a bit by using only data that is already "attached" or defined by some real-world, truly physical object like a person, house, or car. Even today, this is still too often the only definition of objects that people get in software courses. That's too bad, because even trivial object-oriented programs need a broader definition than that.

The second and far more interesting category of objects consists of what I'll call immortalized real-world events. By "immortalized" I mean things that at least briefly exist as a well-defined entity or collections out in the real world, but which then disperse and ceases to exist as physically meaningful collections. A symposium is a great example: The symposium exists for a short while as a decently well-defined collection of places and people. But alas, even the best conferences must end, and the individual parts that made them up move on to other activities.

But by using computers and networks, we can make such a transient symposium seem like a long-term object by capturing and maintaining a memory of it as a software object. A great many of the things we do with computers and databases amount to this kind of immortalization of transient events, in which we in effect try to make our real universe richer by capturing and extending it in ways that cannot possibly exist physically. E.g., have you seen a real Pandora lately? Such captures and extensions of real-world pieces help enrich and extend our own lives, economies, and choices in remarkable ways. This to me is the heartland of object oriented programming, the place where it has had, and continues to have, the most remarkable impacts.

A final category of OOP consists of objects that have no close connection to external events, but are instead the infrastructure needed to support our continuing extension of reality using immortalized objects from the real world. This is where you can descend all the way down to the (semi)metal of the computer, creating pieces of persistent reality that like the chemical elements of the real world can be combined quickly and in interesting ways to build new internal worlds. Mobile computing has helped promote the growth of this kind of highly recombinatorial approach, one that again in many ways mimics the recombinatorial features of the physical world. It is also hard: What may seem like a good choice may prove over time to have been an unexpectedly bad one, usually because it ends up blocking diversity and expansion instead of supporting it.

This last category also points the risks of using just one model for programming, since just like the real world, programmed worlds also need processes that don't correspond well to relatively unchanging objects. Earth is full of objects, but the sun is full of highly dynamic energy flows that ultimately are needed to "drive" the objects and activities on lower-energy earth. Similarly, in creating computing worlds there are cases where you must deal with flows and transformations and rapidly changing contexts that, while not very object-like in themselves, are nonetheless absolutely critical to enabling the simpler, more human-friendly objects used at higher levels. It is no coincidence that much of the programming done at the kernel level is not conspicuously object-like, or that it tends to rely heavily on languages like C that are more processing oriented. These are the deeper domains that complement the fascinating diversity we see higher up in computer generated worlds. Trying to force them into pure object models can be a bit like telling the sun it needs to be re-organized as a few billion tidy fireplace objects so that we can understand and navigate more easily from our humans-first perspective.

The other area where OOP can go awry is focusing too much on old object concepts.

Objects in the real world, and especially living objects, have an absolutely astonishing level of ability to interact with their environments in complex and subtle ways. Composable widgets that look each other over, do some compatibility and sanity checks, and maybe even figure out some new ways to interact come a lot close to the real-world biological concept of objects than do the simple frameworks and simple inheritance schemes that we tend to focus on (usually by necessity!) at the code level. This is one of the growth areas for objects in the cyber world, the more "agent like" approaches where reactivity to environment is the norm even within programming itself.

And so much for my "critique" of OOP! Still, though, I hope I've pointed out why creating a richer cyberworld means encompassing diversity of programming styles, rather than assuming that "just one" is all that is needed. My feeling is that the really interesting stuff is yet to come, no matter how mundane much of what we do now is!

14
  • 20
    I'm sure quite a few people dropped out at the "Read further only if you are interested in a physics-level exploration" part. I am glad I didn't. This is the sort of thinking that shakes the foundations of our understanding, and probably the only way we are going to make notable progress. Thanks for the great read.
    – Matt Esch
    Mar 24, 2012 at 23:19
  • 2
    Signed up to the site just to be able to vote up-this deep-thought, magnificent answer. =)
    – sgorozco
    May 8, 2013 at 16:15
  • 3
    On line with your thoughts, I've been programming for quite a while and became an OOP zealot, since I really saw my coding skills improve dramatically when I adopted it. However experience has shown me that forcing everything into becoming an object can really be detrimental. I now balk at object-to-relational mapping tools (what a mess) or full object-graph serialization schemes that consume 1000% bandwidth compared to a simple binary protocol that just sends over the wire the right amount of binary data that is needed at the moment. Thanks for the great read.
    – sgorozco
    May 8, 2013 at 16:33
  • 2
    This answer is also the answer to why do we still need SQL!
    – HLGEM
    Aug 13, 2013 at 15:42
  • 1
    inf3mo, good points! I wear my physics hat a lot these days, and I've been trying to convince physicists that "classical" (object!) physics is more observer-dependent -- more based on human perceptions, and languages -- than quantum mechanics. Think about it: Even counting requires complex decisions on what is or is not a particular type of "object", even fingers-and-toes counting (seen any atomically identical fingers lately?). Thus objects, as you just noted, are profoundly linked to the very definition of intelligence even is. C takes a light touch, using only count-and-group concepts. Apr 29, 2020 at 13:59
24

Firstly, you don't need OOP for everything, despite whatever dogmas regarding this have been popularized. Unlike Java, C allows function pointers and even closures which opens the door to functional programming and solves quite piece of the problem space OOP handles, because it provides the means of dependency injection. Also cautious use of macros can actually create some very nice things, as sglib proves.

In a weird way, one could see C as a good compromise between Java and C++. Please note I am not saying that C is in any way a mix of both. But in contrast to Java, it is rather powerful language while in contrast to C++ it has manageable complexity.

It is an old language, that has grown reliable and consistent, while not really growing more complicated. And all that aside, it has a giant eco-system and it simply runs everywhere.

4
  • 12
    Functional programming is great, no objection on that. But C is an rather bad language for functional programming. Closures/blocks are non-portable hacks and come with ugly syntax (as well as gotchas, I bet). Even ignoring all that, you still have to care about memory management. C is a useful language, but like with any language, you're just making your life harder than it has to be if you abuse it to use a paradigm it wasn't made for. You can emulate functional programming in Java too (see Guava), but it's not nice either.
    – user7043
    Mar 24, 2012 at 13:59
  • 7
    It's very hard to program in a functional style without a garbage collector. Mar 24, 2012 at 19:28
  • @KonstantinSolomatov: Firstly, that's very subjective. Secondly, you can add garbage collection to C if needed.
    – back2dos
    Mar 24, 2012 at 20:53
  • 1
    If you want a compromise between Java and C++, try Obj-C :) Definitely something every C/C++ programmer should try.
    – Sulthan
    Nov 4, 2012 at 15:30
21

C has an ABI(Application Binary Interface) C++ doesn't. This makes C more useful than C++ in certain instances. If I am going to write a library and be able to ship binaries for other people's use C++ is the wrong tool for the job. If I am going to write libraries that are going to be used by some other language again C is the right tool for the job. I have never heard of a language that didn't support FFI(Foreign Function interface) to C, on the other hand C++ won't work with libraries written in C++ if different compilers are used.

Basically it boils down to C filling a role that C++ is unsuitable for.

2
  • 2
    Mmm.. a C, tomato, and cheese roll!
    – DeadMG
    Mar 24, 2012 at 21:02
  • 4
    Well, C++ does have an ABI. It's just that C ABI is solid as rock while the C++ one changes way too often. Plus a lot of C++ is templates compiled into the using application, so you can't update it. When all the functionality is hidden behind function calls, it's possible to fix the library and keep the application working.
    – Jan Hudec
    Aug 13, 2013 at 12:00
12

Embedded systems and drivers are usually programmed in C. Aside from that there are tons of legacy C systems out there that are still maintained and extended.

1
  • 2
    Yes, C runs on everything. And it's a pretty easy to learn language (compared to c++).
    – BenjaminB
    Mar 24, 2012 at 12:38
12

One advantage of using C over languages like C++ or Java is that there isn't a whole lot of magic happening under the hood. No constructors are run when items are allocated, and no destructors are run when objects go out of scope. There's no name mangling and no vtables. Performance is easier to predict; you don't have to worry about a garbage collector interrupting a routine and throwing off its timing.

Constructors, destructors, name mangling, vtables, garbage collectors, etc., can ease some of the complexity in the code you author, but then that complexity becomes part of the language itself, where you have little to no control over it. You may wind up with longer build times (annoying, but tolerable), larger runtime memory footprint (may or may not be tolerable) or slower performance. With C you can pare away some of that complexity until you're left with the functionality you need.

For example, the C++ string data type is light-years easier to work with than C-style strings, but it's a fairly heavyweight piece of code, and adds some heft to your image size. I've rarely seen anyone make full use of string's capabilities in any one program. C-style strings, while harder to work with, impose less of a penalty in terms of run time and image size, and for a particular problem may be more attractive for that reason.

5
  • 2
    Penalty of run-time is nonsense. C-strings (null terminated) are much less efficient than C++ strings. Also, a string class can be just as compact as C, so long as you don't drag the whole std in.
    – Pubby
    Mar 24, 2012 at 19:41
  • 2
    A toolchain which doesn't remove the unused functions in string that are not used if you statically link the CRT is a toolchain not worth it's salt. Mar 24, 2012 at 20:08
  • 10
    The silly thing is, I work with a library where std::string is not sophisticated enough. If you're really serious about strings, both in terms of performance and capabilities, you're back to using C and doing it all yourself again, though not using plain old char*s to be sure. (Strings are surprisingly complex, even if you are expecting them to be complicated.) Mar 29, 2012 at 21:54
  • 1
    @DonalFellow Interesting. This is exactly why the C standard has always foregone things like strings and hash tables, much as their absence irks me sometimes.
    – Engineer
    Dec 8, 2015 at 10:06
  • @ArcaneEngineer: The fundamental missing data type in C is a "slice of T[]" type which would combine a T* and a size_t, could be indexed like an array, could decompose into a T*, and could be implicitly converted from any T[n] type (with the size being automatically supplied by the compiler). Such a type could allow automatic bounds checking in many cases where it's otherwise impossible, while making many kinds of code a lot cleaner and more legible.
    – supercat
    Jul 2, 2018 at 19:02
11

The same thing that makes a manual hammer popular in an age of pneumatic hammers (air hammers): C is still the right tool for certain jobs.

8

Simplicity, consistency and precision.

It is simple - you don't need a complex development environment, extensive libraries, or a virtual machine.

It is consistent - most C written 10 years ago could compile today.

Precision - it let's you get down to the level of the machine, knowing the memory locations as needed. This is great for performance and embedded hardware.

It's not for everything, bit it's still a useful tool.

2
  • 5
    Better yet, there's a fair chance that code compiled 10 years ago could execute today. Mar 29, 2012 at 21:55
  • @DonalFellows: And, for applications that use plug-ins, there's a fair chance that an application written, built, and released (in executable form) today will be able to use plug-ins compiled with build tools that haven't even been designed yet.
    – supercat
    Jul 2, 2018 at 18:55
6

I cite two points from another answer, because they capture exactly the reasons why I still use C from time to time (it is not my main language of choice, though):

  • C is simple. It lacks the expressivity of sophisticated OOP or functional languages, but its simplicity means it can be picked up quickly.
  • C is mature. The last standard that introduced big changes is C99, and it is mostly backwards-compatible with previous standards. Unlike newer languages (say, Python), you don't have to worry about breaking changes any time soon.

I think this is very true. I learnt C during the early nighties: it was simple, few keywords and constructs, most of the job done by libraries. Then I did not use C for a few years. Around 2002 I needed a fast implementation of an algorithm, I installed a C compiler and implemented it. I know the language, I know what it is good for, what it is not good for (I would never implement a web application in C!), and it is just there when I need it. No surprises.

With C++ I had a different experience. I learnt it around 1995 and it meant a big paradigm switch from imperative to OOP. Great! I used it for several projects until 1999. For a few years I did not use C++ and when I picked it up again (2008) I found lots of new features already in the language, and even more planned (meanwhile introduced in C++11). I got the feeling I have to learn the language again.

As a developer, I prefer mature, stable languages. I like to learn a language once, to understand its design principles, what it is good for, and to use it when I think it is the right tool for the job. I also like to learn different languages and to pick the language that suites my need (C, C++, Java, Scala, Haskell, and so on). What I do not like is to have to learn the same language again and again because it gets developed further and further, and never reaches maturity.

IMHO, a programming language should have a clear, coherent, and stable design. I like the approach of designers like Niklaus Wirth: every time he felt the need for a different language, he designed a new one (Pascal, Modula-2, Modula-3, Oberon). I do not like languages that undergo important changes every 5-10 years: they are like moving targets and I never feel it is worthwhile investing my time to learn them in depth, because the version I am learning now will probably be obsolete in a few years anyway.

In this sense C is IMO a winner: it is good for certain applications and less appropriate for others, but it has the advantage that it is simple and relatively stable.

4

I'm surprised that no one has mentioned Worse Is Better yet. It's over 20 years old at this point, but still eminently worth reading. While at times slightly tongue-in-cheek, it does a very good job of outlining how and why the expedient often wins over the ideal, using C (pitted against LISP) as one of its central examples.

1
  • Things that I put in the category of 'worse but better': English, PHP, Windows. .. McDonald's maybe. Though I still envy/prefer Spanish, Python, Linux, and Artisan French Cooking; as much as possible, if not commonly possible. Oct 6, 2015 at 23:05
2

You probably wanted to ask why people use C instead of C++ despite the fact that when you have a C compiler, you also usually have C++ compiler.

  • C language is much simpler than C++. I don't know any company that uses the complete C++ standard in their coding convention. Take a look at Google's C++ code style as an example: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
  • C is much faster to compile. Thanks to the lack of hard to compile constructs.
1
  • 1
    This link is broken.
    – ar2015
    Sep 14, 2017 at 0:18
1

Because C has a huge user base. Yes it is a bit of a catch-22, but when I ask a question about C over on StackOverflow, I get the answer almost instantly. The same question about Python could take hours to get answered.

With respect to C++, it's IMO more complicated to learn. Furthermore, after having tried OOP for 10 years, I find it's not always useful, and often times it's easier to use procedural programming instead.

3
  • did you compare asking SO questions for C# or Java?
    – gnat
    Nov 8, 2013 at 18:31
  • @gnat it was an isolated example of C v Python (which by the way has more questions asked!). I have no experience with C# (did you notice my not asking SO questions for C# or jav?)
    – puk
    Nov 8, 2013 at 20:11
  • Heh, I find the #python community on StackOverflow is almost always super fast. Though I would be surprised if the C community outranked the javascript community for speed of answers. (Mostly because of volume) Oct 6, 2015 at 23:07
0

Nothing. TIOBE is a worthless index. If you actually look at their measurement, it's an absolute guess- at best.

9
  • 10
    The fact that TIOBE is worthless does not mean C is not popular
    – Raynos
    Mar 24, 2012 at 19:25
  • It definitely does, however, defeat the argument presented in the OP- that C is popular and therefore it must have some use.
    – DeadMG
    Mar 24, 2012 at 20:26
  • 2
    A better measure of C's popularity is that almost every platform has a C compiler
    – Raynos
    Mar 24, 2012 at 21:16
  • @Raynos: That's not a measurement at all. The only thing that means is that it's easy to implement. It doesn't say anything about how many people use it, or why.
    – DeadMG
    Mar 24, 2012 at 22:19
  • 2
    Not entirely, I happily accept opposing view points. Your one line answer appear to have little thought applied, and you are argumentative and nonconstructive with your responses.
    – mattnz
    Mar 26, 2012 at 20:59
0

Lots of Legacy Software

Many companies cannot change, instantly all their code to C++ or similar.

Many companies cannot afford to change their code.

Many companies can afford to change their code, but don't care, or are "cheap".

Many companies are in the process of migrating, but, not yet finished.

Hidden Object Orientation

(Non Object Oriented) C source code designed as Object Oriented C source code, applications that are modeled with Object Orientation, and coded with "pure C", or tools that translate from "C++" or other O.O. progr. lang into C.

I heard that some video games are done that way. Some cross platforms tools also, and the GTK (GObject, GLibrary) visual interface library for the GNome Linux O.S. distributions.

2
  • 3
    The latter half of this answer needs to be deobfuscated.
    – aramis
    Mar 25, 2012 at 0:59
  • @aramis. The second part means: Many code seems to be donde directly in "C", but, actually in other language, and traslated to "C"
    – umlcat
    Mar 25, 2012 at 19:33
0

I see some of the answerers give as to why C is the most popular, it's been around for a long time, it available in most platforms, free, etc.

But the same can be said about other languages, free Pascal for example - it's free, and supported for just about all platforms.

Pascal was invented around 1970, C was invented around 1972, so I think Pascal has been around just as long as C.

Personally I think C is the most popular language because there is just more open source code available out there to be reused by anyone. And yes it lower level than Pascal, so it's getting close to assembly but its a lot more readable than assembly.

I think there are just way too many programming languages out there. As programmers we have to know most of the important ones, but at the end there should be no need for that. One programming language can be implemented to do it all from building websites to iOS computer games.

C seem to be that global language, but I wish it would be something like Object Pascal. Why Object Pascal, it's a more readable programing language, OOP code does tend to be more reusable and less bug prone (in my opinion) than C.

Very large applications are easier to manage with Object Pascal than C/C++.

As to having a programming language that has been the some since the '70, and not liking languages that change every 5 or 10 years. As time goes technology advances and programming methods are improved. If a languages changes drastically every few years then it was probably not well thought out by its designer. But 1970 to 2012 is almost half a century, it's ok to make changes to a language in that time to incorporate advances used in Software development.

C itself has been revised several times. So, it's not better than other languages form that point of view.

1
  • 3
    One problem with Pascal has been that the "official" version of the language left out some very necessary features. For quite awhile, both the PC and Macintosh have had Pascal compilers that were much more usable than any C compilers that existed at the time, but such compilers added language extensions which weren't supported by any "official" standard. I think if there had been an effort to make an official standard which codified such extensions, Pascal could have displaced that hack of a language which is known as "C".
    – supercat
    Aug 23, 2014 at 23:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.