What's To Love About C?
First time accepted submitter edA-qa writes "Antiquated, clunky, and unsafe. Though beloved to some, C is a language that many choose to hate. The mass opinion is indeed so negative it's hard to believe that anybody would program anything in C. Yet they do. In fact a lot of things, even new things, are programmed in C. The standard was recently updated and the tools continue to evolve. While many are quick to dismiss the language it is in no danger of disappearing."
char *post = "first";
It's not the bloated obscenity that is C++.
How is this news for nerds? We already know this old story.
I mean, unless you want to, you know, use pascal or fortran or something.
Someone had to do it.
Personally the thing I like most about C is that it's not "safe". It doesn't take care of a lot of memory management for you and you can easily eat up all the memory or introduce a buffer overload vulnerability if you're not paying attention. It forces programmers to actually look at what they're doing and consider what it will do in the long run, and causes good coding habits to form. I think the majority of people who dismiss C as "too hard" are coming from Java programming. C gives you a lot of power, but, as the well-cliched saying goes, "with great power comes great responsibility".
All the world's a CPU, and all the men and women merely AI agents
A web developer?
C is the the best tool around for low level programming. It allows very high levels of abstraction and it keeps you very close to your architecture's features.
FORTH and C++ are used to the same means, but I do not hear much about other tools being used for this kind of development.
C offers control. If you can't handle having that much control (over memory, how the CPU acts on that memory, etc) then your software will have many problems and you will hate C.
Better known as 318230.
Close to the metal but still not specific to any machine if you do not need to. Easy to understand exactly what machinecode the compiler will produce.
You have to know what you are doing when you C and you can do anything...
It's for cookie.
That's good enough for me.
The power of C is - and always has been - that it is a shorthand for assembly. It compiles very small and runs very fast, making it ideal for embedded systems.
"Stop whining!" - Arnold, as Mr. Kimble
C is going to stay around for a long time in embedded systems. In this environment many microcontrollers still have 4k or less of RAM, and cost less than a postage stamp. In these systems there is virtually no abstraction. You write directly to hardware registers, and typically don't use any dynamically allocated memory. You use C because, assuming you understand the instruciton set, you can pretty much predict what assembly instructions it's going to generate and create very efficient code, without the hassle of writing assembly. Aditionally, your code is portable for unit testing or, to a lesser degree, other microcontrollers. This allows you to write a program that will run in 3.2 k of ram, rather than 4k, which allows a manufacturer to save 4 cents on the microcontroller they pick. This saves you $40,000 when you're making a million of something.
Its a way to tell a machine what you want it to do that ends up doing exactly what you expected in the most efficient way. C++ too, sometimes. Java, never.
It's not dead because all of your VMs and interpreters have to interact with SOMETHING, and that SOMETHING has to be written in a low-level language. I strongly believe in using only the lowest-level language necessary for the job, but for OS development that's C.
Tons of people love to have something to hate. It might be because they don't like something about it...but I think it's mostly because people like to set up communities held together by rhetoric against a tool or technology perceived and portrayed as an enemy.
"C++ sucks. We are at war with C++. We have always been at war with C++.[1]"
Swap out "C++" for whatever language you like.
Certainly there are going to be cases and scenarios where C is preferable over C++, where C++ is preferable over C, or where Brainfuck is preferable over either. Use the right tool for the right job,[2] and the right tool is whichever allows you to most effectively achieve your goals.
[1] Or, at least since its inception. Or since [insert arbitrary date here].[3] ... just wait. Someone will eventually come along and get modded +2 Funny when they reply to you.
[2] For whoever asks "what's the right job for Brainfuck?"
[3] I see what you'll do there, Mr. Connor.
tasks(723) drafts(105) languages(484) examples(29106)
C is a very simple language and yet it allows operating memory directly in a way similar to assembler. C is portable (well, it can be compiled for different platforms), I rather enjoyed the language a while back, but since about 98 I use Java for most of big development and I am pretty sure that if I had to do everything in C that I did in Java, it would have taken me much more time.
C is nice in another way - it allows you and in some sense it forces you to understand the machine in a more intimate way, you end up using parts of the machine, registers, memory addresses, you are more physically connected to the hardware. Java is a high level abstraction, but then again, to write so much logic, it is just better to do it at higher level, where you don't have to think about the machine.
C is great tool to control the machine, Java is a great tool to build business applications (I am mostly talking about back end, but sometimes front end too).
So I like C, I used to code in it a lot, but I just to use it nowadays. What's to love about it? Applications written in it can be closely integrated into the specific OS, you can really use the underlying architecture, talk to the CPU but also the GPU (CUDA), if I wanted to use the GPU from a Java application, I'd probably end up compiling some C code and a JNI bridge to it.
C teaches you to think about the machine, I think it gives an important understanding and it's faster to develop in than in Assembler.
You can't handle the truth.
I don't look at a flat-head screw and grab a phillips screwdriver.
...I'm looking into learning more C from an embedded perspective. A lot of Arduino libraries are written in plain C and I'm venturing to learn more about it to write my own libraries and/or edit libraries that come into conflict with others. And if you're wanting to go outside the usual Arduino chip sets (mega328, 168, etc) then it looks like C is the way to go.
If programming languages were like tools... then this is what I'd prefer over this when I want to build myself a cabin.
--frank[at]unternet.org
That's because there is no difference! I think you meant:
char* const foo;
for the second one. const modifies the item to the left, unless it occurs at the beginning of the line, in which case it modifies the item to the right.
<xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
C shines when developing programs like compilers, interpreters, and operating Systems. It is the right level of abstraction for modern hardware. In fact, I've heard that hardware research is dominated by making C code run faster.
For everything else, which is probably 99% of all software, higher level languages should be used, with C only used sparingly for optimization. Mercurial (hg) is a good example of this; it is written in python but uses some C code to quickly compare diffs and do I/O, and rivals git, which is C with some Perl.
Though beloved to some, C is a language that many choose to hate. The mass opinion is indeed so negative it's hard to believe that anybody would program anything in C.
The masses to which you refer are idiots. C is great. It lets you do what you want, how you want. True, you're afforded enough programming rope to easily hang yourself, but you learn not to, and while most things can be more easily done in higher languages (you'll have to pry Perl from my dead, cold hands), many things can only be done in languages like C or its derivatives. C is one of those languages that separates the adults from the kids, so put on your big-boy pants, stop whinging about it and step up.
It must have been something you assimilated. . . .
Who are these people that hate C? A tool is a tool and some are better suited to a job then others. Even COBOL has it's place. If you want something to compile to true binary code that runs very fast on the target hardware, then C is a great tool. If you want to slam out some code that will sort of run and look okay to the user, how about Visual Basic? Pascal has it's place as does C++ and even ASP.
Huh? What mass opinion? Where's the evidence for this?
Pick the right tool for the job. C is the right tool for some jobs, specifically jobs like writing drivers or operating systems.
Historically, C won by having an innovative syntax for pointers, which a lot of people liked, and it also won by being a small language that was easy to implement. Because it was small and easy to implement, it ended up being widely available. Ca. 1980, the joke was that C was like masturbation: it might not be what you really want, but it's always available. A lot of people in 2012 may not realize that in the era when C was winning popularity, people didn't usually have access to free compilers, and for many types of hardware (e.g., 8-bit desktops like the TRS-80), there simply weren't any good development tools. Another big win for C was that because it was so widely available, it became easy to find programmers who could code in it; it fed on its own success in a positive feedback loop. This is why languages like java had C-like syntax -- they wanted to ride the coattails of C.
IMO the biggest problems have been when people started to use C for tasks for which it wasn't the right tool. It started creeping up into higher-level applications, where it wasn't really appropriate. This became particularly problematic with the rise of the internet. Networks used to be small and run by people with whom you had personal contact, so nobody really cared about the kind of buffer-overflow vulnerabilities that C is prone to. The attitude was that if you gave a program crazy input that caused it to crash, well, what was the big deal? You crashed the program, and you were only hurting yourself.
Find free books.
Lets face it -- there are always things to hate. Or, if you are of a more optimistic bent, things to love. Abstraction is tough, and specifying abstraction oxymonically tougher.
Go ahead. Argue. I dare you.
v same sig since 2002. v
Favorite
Move along, nothing left to C
Mielipiteet omiani - Opinions personal, facts suspect.
I'm writing a game in C. I spent a lot of time trying to decide what language to use for the game: Java, C#, Python, C++. Ultimately I decided that I wanted to write the whole thing myself so I didn't have to rely on any releases of virtual machines.
I find it fun. I write in C++ for my job and that is where I spent most of my education. C is an interesting challenge where I don't get all of my comforts. But, it works. I tried writing the game in C++ and I kept getting lost in infrastructure: Objects or get-it-done function? I had to decide all the time. C drops that for a simple set of rules (to me, but I "grew-up" in C++ so I'm used to managing memory) that helps me get the job done. I'm still learning, and I work on infrastructure some to reduce complexity, but its fun.
Why will the development community abandon C while so many still embrace COBOL or RPG?
Ken
I'm as tired of single-langujage zealots as I am about single-issue zealots in politics. It's a repetition of the old saw: "When the only tool you have is a hammer, everything starts looking like a nail." C has its applications. C++ has its applications Perl has its applications. FORTRAN (remember that language?) has its applications. And so on down the list.
The fact is, a true professional doesn't have a single tool, he has a whole toolbox full of tools from which to select one, or two, or three, or more to get a particular job done. Look at your auto mechanic: he doesn't try to use a screwdriver when a torque wrench is called for. Look at the Web developer: he doesn't try to write C code to do Web sites. And no one in their right mind would write the heart of an Internet router in C++ or PHP or (shudder) COBOL. The tool has to be matched to the job.
Sometimes you do the job multiple times, once in an easy-to-debug language to get your algorithms down and your corner cases identified, then a second pass in a language that lets you get closer to the nuts and bolts -- hey, you already have the high-level stuff debugged.
And then you have people who are more comfortable creating tools to get the job done. I don't know how many times I've written a LEXX/YACC package to generate exactly what I need from a higher-level description...or to give a customer scripting capability suited to the particular task. I call it part of layered programming, and using multiple languages in a project to get the job done right, and in a way that can be maintained.
Finally, programming style helps reduce mistakes, as do good development tools like IDEs that do syntax highlighting.
OK, every language has its shortcomings. Even specific implementations of a language will drive you up the wall with its mysteries. But that's part of matching the language to the job.
I'll grant you that string handling in C sucks. It's part of the charm, though, for some projects, because you don't have to worry about the run-time kicking in to do garbage collection at points in your code where timing is critical. But if the job is text processing without real-time constraints, C is one of the worse choices for a tool. So don't use it for that. Use Perl, or Python, or PHP, or any number of other languages where string handling is a first-class citizen. (For a price. For a price.)
That's the difference between a true professional and a one-hit wonder: the former knows his tools, how to use them, and when to use them.
Lots of people hate manual transmissions in cars, too. That doesn't mean there isn't a place for them. I bought a manual transmission truck for the same reason I use C: it lets me get more performance out of lesser hardware, gives me more control, and it's just plain fun to work with.
Easy Online Role Playing Campaign Management
If you can't code in C you can't code.
That said, unless you are doing low level/embedded work if you can't find a better tool for the job, you also can't code.
C should be _every_ programmers second language at the latest.
The other thing to love about C? Pointers! Pointers to pointers! etc. Coding without pointers might be safe, so is fapping.
John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.
I still have more fans than freaks. WTF is wrong with you people?
After all, in our National Anthem, we ask, "Jose, can you C?"
"To those who are overly cautious, everything is impossible. "
you can pretty much predict what assembly instructions it's going to generate
Which is really important, because sometimes you end up debugging at that level or working hand in hand with inline assembly code.
If there is no OS, or you're writing the OS, C is the way to go.
"Science flies us to the moon. Religion flies us into buildings." - Victor Stenger
Thank you. "const" modifies the thing that preceded it. Iff nothing precedes it, it modifies the first thing that follows it. It's not terribly complicated.
I didn't "get" C until I studied assembler in college. After learning the basics of assembler and machine code, a little light went off in my head, and I thought to myself, "Ohhhh, so that's why C is like that!"
C is structured in a way that is very closely related to the way computers function. Maybe if CPU's become radically redesigned, another language would become more practical, but it doesn't look like anything is going to change at that level any time soon.
Well, C++ basically has all the same properties. GCC, for example will happily target really very small ATMEL micros.
SJW n. One who posts facts.
It's a very high-level language that ultimately compiles to machine code - and you can stop anywhere in between if you want to look at how it looks with the macros expanded out, or if you want to look at how the resulting high-level macro assembler code looks, all the way down to how the machine code looks.
You've got total control over the code right down to the binary that the CPU runs.
If you want safe, then the only place that suits you is a mental hospital. C is indeed not safe. It's a Swiss army knife. You can use one of its blades to slit your own throat. Many people still like Swiss army knives though. You cannot carve wood or cut bread with fluffy toy animals.
All the automotive C programmers I know use a subset of the language -typically a subset of C90. In my team we throw gcc at the source with all the warnings switched on, splint at checks level - no annotations allowed and two MISRA static analysis rule checkers before the cross compiler gets a go. Our code also goes through Matlab/Simulink legacy code tool to give us an additional layer of performance data. After cross compilation the on-board unit tests ensure 100% coverage of the binary after which the whole lot goes through hardware-in-the loop. The vast majority of this is automated and avoiding regression failures is paramount. The build process uses another 10 or so languages including Java for various things. I've seen some more recent languages in use on one other subsystems (the HMI) and the robustness of the software is terrible. When software absolutely has to work every time it's hard to see how we might integrate some other language that further separates us from understanding exactly what is going on. The availability of cheap C cross-compilers for cheap micros (mine is an 8Mhz device) is another factor. The comfort factor of the gauntlet of testing and analysis that we can throw at the source is probably going to be the most difficult hurdle.
Now if everyone stops learning C and it's not possible to hire good C programmers in 10 years time then you'll see the landscape change overnight.
We write and maintain about 20,000 lines of source, 40,000 of SIL tests (unit tests) and another 25,000 of hardware in the loop tests for a climate control system for a supercar.
Wrong. C++ == C always evaluates to true.
C and C++ (I consider them essentially the same, if only because I write them essentially the same) have a few advantages:
They work. A language update doesn't break your actual programs. It may break your ability to compile them, but you still have a working binary compiled with the old version, which gives you time to make the code work with the new version. You never have to run around like a chicken with it's head cut off because some automatic Java or Python or PHP or __LANGUAGE__ update broke __BIG_CRITICAL_APP__.
The tools work. You have IDEs that actually work. You have debuggers that actually debug. You've got static analysis tools that actually analyze (I've seen some PHP "static analyzers" that actually just make sure you use a particular code style!). If you want, you can grab the intermediate assembly files and debug *those*.
The coders work. Sure, C[++] has some really awful language features, but the programmers know about them, know how to use them properly (which, often times, is "never"). It's a language known by any decent programmer. Maybe not used, or liked, but pretty much everyone can read C.
It does things many other languages can't. You cannot (last I checked) embed assembly snippets in any other major language. There are many libraries that only have C APIs.
It's fast. Game developers, serious ones, use C++, because even Java is still too slow. And when you have 20,000,000 vertices you need to render every 16ms, speed *matters*. That's why web servers are written in C. That's why operating systems are written in C. That's why other programming languages are written in C. Because sometimes, processor time actually *is* more expensive than programmer time.
I *like* C. That game I program in my free time? It's C++, but it acts like "C with objects and strings". Sure, I could have done it "faster" in another language, but I know C and like C, for all the reasons enumerated above.
Among the many benefits of C overlooked by some apparent `mass opinion' is portability. C compilers are easy to create. Things written in C can be compiled on platforms that provides a C compiler. C has been the lingua franca of mature system software for over 40 years; it's the first thing you write after you have a working assembler.
This situation won't change until someone makes a real alternative. Lots of things purport to offer an alternative but are actually not; they are complex and require sophisticated compilers and memory management schemes. C is simple. Any alternative must be at least as simple to be considered.
It isn't hard to imagine an alternative. C is not perfect. The problem, in my opinion, is that no one has really tried; language designers seem to be interested in only higher level problems and are happy to muddle along ignoring the flaws of C.
Yes, but it won't work at all unless you explicitly tell your compiler to ignore the vast majority of C++ features and basically just write C in C++. You can use objects without incurring too much bloat, but don't even think about touching the STL or templates in general.
For comparison I made up a pair of Hello World programs, one in C and one in C++. The C version compiled down to 3220 bytes (still outrageous), but the c++ version came in at a whopping 4876 bytes, completely blowing away the 4k memory budget the op talked about.
I read the internet for the articles.
The primary implementations are written in C. Python is also implemented in Java, C#, and yes, even Python.
First, in why does php suck so much, we got to see all kinds of nonsense answers by people who don't understand programming fundamentals. In why do we need command lines anyway, we got to see people discuss getting rid of the command line, as though it's a legitimate option. And in, why can't I understand the core principles of C, we're going to see more of the same. I have a question for Slashdot: Why are you publishing nonsense questions?
This signature intentionally left blank.
Well, I was going to try to prove my point by giving an example disassembly from SBCL, to show that a high level language with modern features can be compiled to bare metal, but the lameness filter stopped me. Still, Lisp has been compiled to metal for a long time, and it is not nearly as painful as using Pascal, Fortran, or C (unless you really hate parens).
Palm trees and 8
And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.
Hmm. I wonder why there's so much animosity towards C? It's a mystery.
by Mike Buddha -- Someday the mountain might get him, but the law never will.
I C what you did there.
And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.
You might actually want the pointer to be able to change. You may have a pointer to _some_ literal string, but want to be able to change _which_ literal you are pointing to.
C is great because the language as simple and portable. The complex goodness comes in the libraries. Java tries the same approach, but modernised (hence, the enormous success of C and Java). C++ does not have simplicity as its goal, which makes it horrid to read someone else's code.
It's the language closest to assembly, which makes it a great language for microcontrollers. In fact, most of the microcontrollers only come with assembler and C programmer, though many understand some convenient C++ features.
EARWORM!
It's a small world and it smells funny; I'd buy another if it wasn't for the money; Take back what I paid (SoM)
Oh, no, it's not a mystery. The animosity comes from ignorance and lack of ability. Many newer programmers have never programmed in assembly language or C, and would not be able to build a computer out of logic chips. This same demographic has learned Java and believes that Hashmap is a magic O(1) thing you can just smear onto any algorithm. C was initially popular among people who were, in fact, able to build computers out of 7400-series logic, or even transistors, if need be. In other words, the animosity comes from those who aren't qualified to judge.
Wait, what does happen here?
Isn't it incrementing C, taking the previous value of C, and comparing with the new value of C? Or does the increment only happen after a sequence point?
Sometimes. But let's be honest- how many times when you write const char* foo="some string" do you really want that? It's a miniscule fraction of the time. Almost all of them should be double const.
I still have more fans than freaks. WTF is wrong with you people?
*The iostream libraries.
Well, I like the type safety of the C++ library.
But are you willing to spend a quarter megabyte on type safety? I tried making hello world with <cstdio> and hello world with <iostream> with statically linked GNU libstdc++. The <iostream> versions were about a quarter megabyte bigger on both i686 and ARM-Thumb. And no, you can't use a dynamically linked C++ standard library on an embedded system that doesn't already have such a library in ROM (such as a handheld video game system) or on a compiler whose C++ calling convention doesn't match that of the operating system vendor's own C++ standard library (such as MinGW).
All languages are equivalent in what they can do (See Turing Machine). However, you pick a language that makes what you want to do easy. For twiddling bits, for writing fast algorithms, for controlling hardware, for lots of common programming tasks, C is the simplest language that makes those tasks easy. There are things that are tedious to do in C (like doing complex things with strings), so in those cases you pick another language that is more appropriate. Something that might take up 5 lines of Perl could take pages of C code, but there's no point in writing a Perl script for something that can be easily done with a few lines of C. The C program will be smaller and faster, and probably easier to understand.
So there are lots of things to like about C, when it is the appropriate language for the task.
If C is volatile and changed by a different thread, your statement might actually evaluate as false.
Two, the library. You may have some complaints about the library, but in the right hands a person really can control every aspect of a UNIX system with it. I've had to write process watchdogs at a couple of different companies. These were programs that would kick off another process and monitor its status. That is remarkably easy to do in C. It's a little harder to do correctly but it's still pretty nice. I still hand-code socket servers from time to time. That's also pretty easy with C and the standard library. Actually IPC in general is quite accessible. Handling time... easy. Checking filesystems to see how many blocks are left... easy. The list goes on.
All those utilities we take for granted are all implemented in C, and you can get at all that functionality if you need to. Once you've done some system level programming, the constraints of less mature languages become annoying very quickly. Compare the capabilities of Java's "Process" to what you can do in C, for example.
Sure it's dangerous. Sure there are corner cases you might get caught at. But really, the corporate software development model is far more dangerous, no matter what the language. If you code small, tightly focused libraries and unit test them, whatever language you use is probably pretty safe. If you code some monolithic abomination with half a million lines of tightly coupled, untested code, you're probably going to run into problems anyway. In 20 years of software development, I've never seen anyplace actually write smaller libraries and link them in. Hell most of the places I've worked either didn't have version control or were using it incorrectly. If your company puts up with bad programming, it really doesn't matter what language you're using.
I'm trying to teach myself to set people on fire with my mind... Is it hot in here?
The animosity comes from ignorance and lack of ability. In other words, the animosity comes from those who aren't qualified to judge.
Exactly. Unless you guys can make device drivers in Visual Basic like me, you're not qualified to put down the language.
(Except in C++, where it could mean anything.)
Brian Fundakowski Feldman
Oh I know this one! Is the answer: "Being unable to access the carry flag" ?
From one of my facebook posts a few months back...and a true story (with a bit of embellishment):
So I mentioned at work in the company of a flock of Java programmers that I was playing around with writing web applications in C and C++. The collective gasp of horror...and I mean literally HORROR...on these people's faces was hilarious. Apparently, amongst many Java developers, writing anything in C or C++ is equivalent to making a pact with the Devil. Now, I agree that there are A LOT of reasons to NOT write web apps in C or C++, but the outright FEAR in the eyes of these developers of my snubbing the Programming Gods by writing code without my talisman of garbage collection, my sword of strong typing, my shield of virtual machines (which we all know are just interpreters), and heaven forbid, going out to do battle without ANY object-oriented paradigms (in the case of C...and keep in mind...the ENTIRE world...without exception...MUST be modeled as a class...even something like an integer) brought these people to their knees shaking in holy terror. Ah well...the circle is complete...as that is what I am certain my mother referred to me when i was but a small lad...Holy Terror!
One of the best features about C++ is that you can define your own subset that you'll use.
One of the worst features about C++ fanboys is that if their subset doesn't match your subset, you get subset holy wars with "no true Scotsman" fallacies all over: "no true C++ program uses <cstdio>".
Worried about exception handling? Then don't use them!
The entire STL uses new, which throws std::bad_alloc on failure, instead of new(std::nothrow), which returns NULL like old-school std::calloc. So how would one handle out-of-memory conditions on an embedded system with no swap file without A. being unable to use the containers and algorithms of the STL or B. reimplementing the whole STL yourself to use instead of throwing std::bad_alloc?
I have a C library. I can dynamically import it into C, Python, Java or C# fairly easy, on any platform
I'd temper that to "almost any platform". Otherwise, good luck importing a C library into a C# project on Windows Phone 7 or Xbox 360 XNA. These platforms have no support for native assemblies and throw a security exception when you try to P/Invoke. Likewise, some pre-iOS smartphone platforms based on Java Micro Edition give no JNI privileges to user applications.
C is basically logic algebra. Its syntax and computing model are the essence of iterative processing. It's a great lingua franca (universal language spoken by all, even if it's frequently far from the best in expression). Most programmers and machines speak it.
If C didn't exist, we'd have to invent it. All hail the almighty C!
--
make install -not war
You can use objects without incurring too much bloat,
Well, that's already nicer than using plain C.
but don't even think about touching the STL or templates in general.
You're not going to be using std::vector on an atmel micro, but then you're probably not going to be using iostreams either. If you're using printf, then it's certainly not the C standard one with locales and whatever.
Using something like std::sort, std::heap or std::bitset is not going to induce bloat.
SJW n. One who posts facts.
If you can't get into serious trouble in a language, you're also limited in the good stuff you can do.
Oh, I know, it's *so* old, it wasn't invented in the last five years. Oooh, cooties, it was invented last *century*: who'd want to use *that*... never mind it's fast, and can be clean and elegant, if you got past the crap you wrote when you first got out of school, with no error checking and handling, and whatever the professor who made the biggest impression on you's Favorite Tool was (i.e, I worked with a guy many years ago who seemed to think that *everything* should be done with recursion).
Easier to debug, too, when you don't have a stack of inherited increasingly complex stuff to write "hello, world".
mark
This makes it very nice for all kinds of embedded environments.
Efficiency matters. Python is great, but you don't want to use it for embedded work.
-- Erich
Slashdot reader since 1997
Fully one-fourth of these questions ask about aspects of a specific implementation, not the C standard, and "implementation defined" is not an option.
Questions 3 and 18 on the quiz assumes that int is 32-bit. Question 3 assumes that unsigned short automatically gets promoted to signed int because no values are lost, but that's true only if sizeof(signed int) > sizeof(unsigned short). It's not true on platforms with 16-bit int, for example. Question 18 states that the answer is correct "as long as the int type is wider than the short type", which again is not the case if sizeof(short) == sizeof(int). Question 12 does the opposite; the answer is wrong if int is 64-bit.
Questions 4 and 5 cover implementation-defined behaviors and assume familiarity with the x86 and x86-64 ABIs. I happen not to own an x86-64 machine, and I understand some widely used ARM ABIs differ by having char default to unsigned. Question 4 implicitly asks about x86 and x86-64, while question 5 dishonestly doesn't mention which implementation is used until the answer.
Let's face it, C is just an overblown BCPL - let's get back to basics...
-mark
C
Sea
See
OK, maybe not so easy after all.
Knowledge is how to play a game, intelligence is how to win, wisdom is knowing what game to play.
Let's face it: How much new code have you really written over the course of your career? Most of the code I've worked with is legacy and it's not going away.
C and its slightly less unattractive cousin C++ are here to stay. Companies have too much money invested in their working code base to just wipe it away and start over with some new wiz-bangy language.
For one thing, I thought most applications using HTTP cookies were written in a managed or dynamic language. The song should have gone like this:
Perl is for cookie, that's good enough for me
Java is for cookie, that's good enough for me
Python is for cookie, that's good enough for me [In this line you may substitute Ruby or your favorite pet language]
Oh, cookie cookie starts with PHP
Besides, Cookie Monster has started to sing that a cookie is a "sometimes food". Does this mean C is a sometimes language?
For comparison I made up a pair of Hello World programs, one in C and one in C++. The C version compiled down to 3220 bytes (still outrageous), but the c++ version came in at a whopping 4876 bytes
That's nothing. I saw a quarter megabyte difference between Hello World using <cstdio> and Hello World using <iostream> (and static GNU libstdc++) after stripping. But then the C++/<cstdio> and C/<stdio.h> versions had the same size in bytes.
However, the parent made a point using the tool of sarcasm, that there is a lot of animosity towards C out there. You see it really wasn't a mystery to him at all. On the other hand you made an interesting but tangential point about the intelligence of such people.
If you want to write code that lets you go from idea to executauble in a short period of time but you don't care about efficiency, use a tool that does most of the work for you and which protects you from most implementation mistakes. Java, .NET, and other library-rich, managed environments do this well.
If you want control over how things really work, use a tool where YOU know the libraries' performance characteristics, where YOU know the tool's "managed-code" characteristics if any, and YOU have the ability to tune them to your liking.
Yes, you can "be naive" in C and have severe performance bottlenecks when you call a library function that is a total performance mis-match to what the rest of your code does, but it's a lot easier to be naive in Java or .NET.
Knowledge is how to play a game, intelligence is how to win, wisdom is knowing what game to play.
I wish C could get closer to the metal.
Only way you can do a 3-way comparison is hope the compiler optimizes it into the code.
Switch statements are another place you have to hope the compiler can optimize. For simple operations, it's easy enough to whip up a lookup table and not use switch at all, but if you need to call functions from the cases you're looking at using function pointers. Always takes me a fair amount of trial and error to get the syntax of a function pointer correct, and then it still might not work. Easier to forget it and let the compiler turn a switch statement into a series of comparisons.
Multiple entry to functions is another feature that isn't readily available. You can inline functions, and the compiler might heed you, or might not. In any case, inline doesn't help with this problem, just the opposite if anything. With macros, you can kind of do it in source code, for clarity, but the compiler will generate separate functions, rather like template functions. The MNG library is a good example of code that could use multiple entry. Lot of functions that are identical except for the input parameters and first few lines. Mozilla kicked MNG out of Firefox for being too bloated. Multiple entry might have shrunk MNG enough to save it.
C does have a GOTO statement, but it should be used only in very controlled situations. I've never tried using GOTOs to implement multiple entry. Don't need it to skip the initial check of a while loop since unlike some languages (*cough* python *cough*), C has a "do while" loop. Only used it to exit nested loops, and for that I prefer to wrap the loops in a function and use return.
Intellectual Property is a monopolistic, selfish, and defective concept. It is "tyranny over the mind of man"
If it did, it would probably be one of the later things to try and optimize.
Consider a platform that has 256 KiB of 16-bit RAM for code and static data and 32 KiB of 32-bit RAM for BSS and stack. New programs are loaded through a serial port on the top of the device. Tens of millions of units of this device have been sold. After seeing Hello World take up 248 KiB out of 256 KiB already, would you still consider size-optimization at this phase premature?
What's wrong with C is the function call conventions. Where a function needs the first few arguments placed into specific registers or the stack, and returns things in a specific way. This can be a performance bottleneck, because data needs to be moved around just to place it in the correct positions, and back again.
So what optimizers to is inline the functions, so they can avoid all the rigid restrictions placed by calling conventions, and the performance problems that come with them.
Sure, calling conventions provide a standardized way to deal with unknown functions that aren't in the same source file, but the biggest advantage of hand-coded ASM is that you don't necessarily need to use them.
All languages are exercises in abstraction, some more than others. That's the very nature of a computer language. They all exist to translate human intentions into something that can run a very, very, very complicated machine.
C is less of an abstraction than some other languages. That does not mean it is old fashioned or outdated.
Arguments that C is unsafe or dangerous miss the point. It isn't the language that is not safe. It's the programmer. If a programmer writes unsafe code in C, that programmer does not know his or her craft well enough.
If C was unsafe, Unix would not exist.
-- Slashdot: When Public Access TV Says "No"
Don't use includes unless they're from a trusted source, then.
Though in the example given, even without any documentation at all, a ten line noddy program would tell you the answer wouldn't it?
Confucius say, "Find worm in apple - bad. Find half a worm - worse."
So what's the standard way to guarantee that one object will be constructed before another object begins to be constructed? If this is undefined in C++, as I suspect, what's the standard workaround?
Objects in variables (whether static or auto or member) within a translation unit are constructed in the order in which they are defined. So just define them in the order you need.
If you mean globals referenced across translation units, then the usual workaround is to hide the global inside a getter function as a local static, and export that function. Local statics are initialized on first call, so unless you have cyclical dependencies, your order of initialization will match the use order.
Not that I would recommend running Java on a pacemaker, but there is really no need for a pacemaker to create new objects, so the GC would never run anyway.
But I'd argue that it is still more complicated than need be, as determined that people don't remember it. Why not just make it "const modifies the thing that preceded it. Final". Or maybe more English-like where the adjective precedes the noun.
To paraphrase someone: There are better languages than C. There are also better languages than English. Unfortunately, the world has latched on to both.
Information theory is life. The rest is just the KL divergence.
You can't handle the truth.
Comment removed based on user account deletion
"C combines the power and performance of assembly language with the portability and ease-of-use of assembly language."
about 50% of them are actually below average
Actually, exactly 50% of them are below average.
That that is is that that that that is not is not.
Disclaimer: I'm an Objective C Programmer by day
The LLVM compiler suite is tremendously powerful with Apple's billions advancing many select features, but key to it's success from a users prospective the core use of reference counted object graphs (of type 'id') and reflection (RTTI - via 'isa' and 'Class'). Obviously this means the entire language is dynamically typed at runtime, but with express qualification in 99% of the code you'll use there's absolutely no performance hit despite the ubiquity of the core object.
I worry that many C programmers will remember RTTI was once considered an unportable disaster in C++ because of the the many differing implementations owing to a spec that left the implementation up to each compiler... Don't let this kind of talk scare you! Although objective, objc is contained to a well defined spec, single inheritance and nary a template in sight.
I consider my programming work to be relatively easy. 50% of my ease comes from the object system above. The other 50% from the fast messaging system used in place of raw ADTs: In the objc world a nil object doesn't fault when messaged (in a C world dereferencing a NULL pointer, common if a struct fetching function fails and then passes NULL on failure) leads to all manner of crashes, or as seen recently, kernel exploits. The messaging system can even push around primitive values, not just nasty objects.
If you program in C, you may have missed Automatic Reference Counting, if you have, low and behold, it's amazing: at *compile time* the compiler adds lifetime qualifiers to the IR that automatically inserts retain and release messages (retain is +1 on alloc, -1 on dealloc - release occurs at 0). In other words the lifetime of an object in objective-c is now exactly the period of acquisition to last use. Yes, last use. ARC's use of a new 'weak' reference means that dangling pointers are a thing of the past: a __weak object is automatically nil'ed after last use: in all local instances of that object (did I say nil objects don't fault on message?).
Admittedly most of what I've mentioned is thanks to the advances in LLVM's Clang compiler, in particular it's static analyser, therefore much objc analysis also benefits C (LLVM's IR is quite specular ).
I could go on: methods can be heap objects with cblocks, objc encourages abstract programming with delegates, you can method swizzle at runtime, extend existing classes and link to C/C++ code.
It's quite a bit simpler than that. * associates right to left, most other things left to right. const is just an innocent victim.
You are today's winner!
Stick Men
Pascal's retarded cousin. The bane of my life but unfortunately it's normally the only language available for micro-controllers.
A pointer is something that points to something else. He was trying to make it easy for you to visualize the concept but apparently he failed.
Those ignorant fools probably need to get off your lawn too, eh :)?
I've programmed in assembly and C. I lack the patience to build a computer out of logic chips, but I've at least designed some stuff in logic gates. I've also implemented hash tables. Yet I still don't particularly like C, mostly because I find the syntax clunky. Specifically...
* Semi-colon line endings are stupid--they serve little purpose besides making compilers easier to write
* for (...;...;...) syntax is less intuitive than eg. VB.NET's "for a = 1 to 10" or numerous alternatives
* declarations are unintuitive (and complicated; see post above for example)
* I'm not fond of curly braces--I like Python's indentation better
* Why make logical operators symbols instead of words?
* operator precedence can be unintuitive
* = vs. == causes bugs (many languages have the same trouble though)
* comments (//) use two characters instead of one
* switch's use of break is worse than eg. Ruby's case statement with commas
(I have other issues, like disliking how many mundane details you have to specify in C compared to other languages, but you need a language like C for certain tasks and it'll need lots of mundane details to translate almost directly into assembly anyway.)
Good to know you were hiring programmers, and not engineers, using this relatively pointless gotcha.
And I really didn't mean to post anonymously :) Thankfully, I know my C a lot better.
Comment removed based on user account deletion
C has the raw power of assembler and can have the sleek elegance of Pascal. Period. What else can you possibly wish from a procedural language? And, yes. I learned assembler (Z80, on Sinclairs) before I learned C. Nowadays, I often teach programming languages, and strongly believe that C (and maybe a little assembler) should be a mandatory learning step under each programmer's belt. I prefer coding in OO langs,but when you need to get your hands dirty, C. Period. :)
So, do you build your own carburetors? How often do you regrind the gears in your car's transmission?
The above may seem silly (and not meaning to incite), but your argument is essentially that anyone who can't build a model T in their garage is incompetent to drive a car.
Considering that a modern microprocessor has on the order of 2 billion transistors with many capabilities that used to defined by simple compilers and operating systems such as memory management, multiprocessor scheduling, programming for such machinery is a far cry from programming a 6800 - itself a bit past the usual assemblage of 7400-series chips. Compilers, linkers and future program generation systems must handle the complexities, which are already well beyond any individual programmer's capabilities to write optimal code for, just as modern fuel injection systems provide much better engine control than any carburetor, much less any manual spark-gap and fuel mixture control. It might be fun and entertaining to adjust the fuel mixture on your Model T as you drive in the parade, but it is not appropriate for driving a car with maximum efficiency on the freeway and in town.
Continuing to use what has been described as a 'structured PDP-11 macro-assembler' for general purpose applications programming is like driving a Model T on the turnpike. And it's arguable that even for embedded use an AI-based program generator should by now be able to optimize better than almost every human programmer in nearly every case. If not, then that area of research is overdue for deeper study.
It's easier to be a result of the past, but more fun to be a cause of the future! http://www.spacefinancegroup.com/
We only care about the opinions of real programmers.
If you aren't a C programmer then your opinion of C doesn't count.
“Common sense is not so common.” — Voltaire
Although the failure modes differ, 'C' and its interactions with its typical user isn't less safe than Java.
'C' programmers know that they need to free their resources and make a habbit of it. Half decent ones even use a naming convention which implies dynamic allocation (ex: message_alloc) and suggests that code readers remember to apply a corresponding function when they're done (message_free).
Java programmers generally assume that their resources will be garbage collected soon enough. While often true for memory, failures involving non-memory objects like file descriptors are not uncommon.
'C' programmers almost never use a goto to get out of the middle of a function. Java programmers both do so regularly (in the form of exceptions) and neglect to catch/cleanup non-memory resources/rethrow.
I'm sure there's going to be a niche for that, but "embedded" like my CS professor used to call it was anything that was smaller than a laptop, like say my cell phone. Today my cell phone has 512MB of RAM and absolutely nobody wants "standardized assembly programming" for that. So if you exclude everyone that's into desktop, mobile or server software, the market for C programmers should be a small niche full of people making washing machines, microwaves, traffic lights and the like. Instead C is still being used a for a ton of high-level software. I think mainly because C# is controlled by Microsoft and Java has had it's own reasons, not because C is the best tool for the job. I like C++/Qt because Qt takes a lot of the C++ fiddling out of it, but I'd love to see something better.
Live today, because you never know what tomorrow brings
fnord
Escher was the first MC and Giger invented the HR department.
me like C
Not a good analogy. Driving a car is more analogous to using a program than to writing one. So perhaps a better analogy would be anyone who can't build a model T in their garage is incompetent to be a mechanic. While that's overkill, there's some basic truth there. My experience is that people who didn't grow up on assembler and/or C have a very fuzzy idea as to what a pointer is, and often as to what a stack is or a memory space. It's particularly bad with people who learned Java as a first language.
If you mean globals referenced across translation units
Yes. For example, in Allegro or SDL, one must initialize the entire library before opening a window, and one must open a window before loading any textures (so that the pixel format will be known), and one must load the font texture before displaying "Hello World".
No, we stick with C because it is a great middle ground between assembly and high level languages. I would not want to write Python or Java on little microcontrollers. C is a small enough language that lets you write complex code relatively easily while staying close to the hardware.
C's got its warts, it's true. It's a mature language that leaves the programmer in control of the system. It's not supposed to do the fancy things such as garbage collection, object management and so on. I'm glad it doesn't. There are other languages for that.
C is useful when you want a compiler that optimizes your code but not so much that you can't control what happens on the byte scale. Nowadays, it is mainly for drivers and embedded software. C is a bit harder to use, but fast, small, concise, and close to the hardware will still keeping a decent amount of portability.
The Wise adapts himself to the world. The Fool adapts the world to himself. Therefore, all progress depends on the Fool.
I did C++ for a very, very long time (20+ years), and yes, you can take a nice subset of c++ that is not bloated, and in that case it's a nice language.
The problem is when you work with other people. They'll drag in all the bloat they can, templates, RTTI, stl (ick), and... boost (arrrgh). And you end up with code that is actually giganormous, and runs slower than Java. I'm not joking, try stuff like OpenSCAD (chokes on 2 pages of geometry) or Code::Blocks (lags like crazy when editing the smalest of file) then there is the obvious KDE desktop, and many others.
So a few years back I reverted to C99. C99 actually had some features that c++ lacks (complex struct initialisation for example) and after years of C++ you know enough about putting structure into your code that you don't /strictly/ need classes anyway. In fact, after a while, you start to realize that in many case, you /don't/ need classes -- sometime you can reduce a problem to 2 or 3 functions, you don't need the 24 accessors, 5 constructors and all that fluff.
It's very refreshing try it. I think you can pick up good habits by hacking on the linux kernel and stuff like qemu/kvm... that sort of C project uses very complex constructs, all in C, and all in a 'clean' environment, there is a LOT to learn in these projects.
The only thing I miss is references; thats the ONE thing I'd like to bring back.
Oh, and if you want slightly smarter memory management for struct-like-objects and that sort of stuff, do lookup "libtalloc" -- it's a little bit of samba that is well worth the look at..
I still like my analogy. For most of the programming I do, the problem I am solving can best be viewed as exploring an unknown space (the logical space within which the problem resides), looking for a reasonably efficient, reliable and repeatable path to the desired solution locus. I may incorporate a wide variety of mechanisms, even sometimes including running shell programs or database queries via ssh on remote machines. This could all be theoretically done by writing everything in C, but there is no reason - especially considering that the environments that I am working with may change radically without notice, so the entire application has to be restructured as fast as possible. Using dynamic languages is certainly in this case the correct solution (I won't go into which one is best.)
So for me, the mechanicing is just part of the navigational problem - deciding which wrench to use and so forth.
Having been in this business now since the days when most computer graphics programs were written in FORTRAN, (my very first language was ALGOL 68) IMHO even such things as device drivers are also easily viewed in this navigational paradigm. As an interesting example, the old Burroughs mainframes and operating systems were first built (together) entirely in software, using mostly formal methods. Then the parts of the system that required the most speed were implemented in hardware. Thus the 'mechanicing' was really just part of the navigation. (However there is the black art of micro-coding, where the timing idiosyncracies require a bit of 'creative destruction' on the formal model.)
The mostly-dynamic languages I use, in fairness, are all largely themselves written in C so could be considered mere C applications, in the purest sense - the compilers or interpreters of few modern languages are themselves written in the target language as the original C was. But regardless, for nearly all programming tasks, even so-called 'bare iron' problems of interfacing to strange hardware, a well-defined model of the hardware and of the problem should be enough for a smart 'compiler' (for lack of a better term) should be able to figure out how to build the driver with little or no 'memory pokery' by a programmer. The fact that C programming is still widespread is a testament to the insufficiency of our tools.
It's easier to be a result of the past, but more fun to be a cause of the future! http://www.spacefinancegroup.com/
Although a number of things contribute, the popularity of a language certainly increases a perceived animosity. Heck, look at PHP.
And, for those two languages, the ability of the user to shoot themselves in the foot probably doesn't help either.
amusing. C & lisp are the best languages available currently. Sooner or later, a developer will become to love them as long as they do not quit programming job.
Uh, why did I get modded flamebait?
Yes, and like firearms, you need training and instruction before use.
C like firearms, requires training and instruction before use.
I wouldn't put a firearm in the hands of a 6 year old, a politician or a banker because obviously the 6 year old will hurt themselves and the politician and banker will give it too someone else to shoot you with. (or...quite possibly the attorney general would just ship it to mexico and have drug gangs kill you....but I digress.)
Likewise, I would not give a C compiler to a asp programmer or visual basic programmer. The asp programmer would crash the server, and the visual basic programmer would unwittingly put back doors in the software they write to which they would exclaim:
"Jeepers, how did that happen?"
-Hack
Got Geometrodynamics? Awe, too hard to figure out? Too bad.
And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.
Hmm. I wonder why there's so much animosity towards C? It's a mystery.
Because they don't RTFM? I mean, c'mon, the rules of reading type C declarations have existed for, like, what, 40 years already.
And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.
Sometimes it depends on the situation (typically for performance reasons) when you do not want that. I might want a const char* (yeah, I prefer to put the const on the left side of the type when declaring a pointer to const).
And I might want it to point to something const... but that something is still not available, or it might change over time. Yep, the const doesn't necessarily denote const'ness for the duration of the execution (though it usually means that.) It simply means that the compiler agrees to treat that which it points as read-only, from the point of view of the observer, at that moment in time.
One good example are the CORBA::Any extractor operators as found in the CORBA-to-C++ mapping (mind you that this is not longer just C, but C++. However, the concept still applies.)
The CORBA::Any extractors contain the following operator signature:
Boolean operator>>==(const CORBA::Any& any, const char*&)
It takes a reference to a pointer to const. It modifies the pointer to const so that it points to an internal, read-only buffer for performance purposes. Should the caller decided to make changes, he/she then creates a duplicate.
And although this is C++, the same can be done with a (const char*)*. Certainly that this can be abused with horrific results, but that is one beautiful thing, that the language allows you such a construct (should you have a valid reason.) At the end of the day, the onus must always reside on the programmer. His success or fuck up should be his and only his, not the compiler or language.
Beyond this specific niche scenario, I generally do not do const-pointer-to-const because the extra step does not add me any extra security that cannot be obtained by simple coding conventions. I simply settle with pointer-to-const.Not that I'm saying the extra benefit you claim is non-existent, but I simply do not think it is a great advantage either.
I would even say that, the practice is not common (can't recall ever seeing a POSIX function with a const-pointer-to-const, but I recall many with pointer-to-const). And since the practice is not common, if I were to see it in the wild, I would assume there is something specific in the design, or algorithm, that requires the pointer to remain const as well, else here be dragons. I would have to spend extra time (perhaps very little, perhaps a very fucking lot) to determine if the const'ness in the pointer is actually critical for the execution of the algorithm under review.
That is, for me, the code should say no more or no less than what it is functionally required to do.
YMMV of course since I cannot claim my POV is devoid of subjectivity.
How far how fast was what I wondered.
Thank you. "const" modifies the thing that preceded it. Iff nothing precedes it, it modifies the first thing that follows it. It's not terribly complicated.
It is for the garbage-collector-pampered crowd :)
Doesn't have to be that old. I wrote, and am still maintaining a program written for an MSP430 that fits into 13k (ok, 12.8k) of code, as it was a 16k part and 3k was used for the bootloader + vector table. It's running right now, controlling power supplies and running PID loops. Actually, it's running about 750,000 copies right now, 24 hours a day, 365 days a year. Which is why it had to fit into 16k. Every penny counts when you multiply times 3/4 million. And yes, of course it's in C. No worries about memory leaks though, there's no heap. I do worry about the 80 byte stack though, maybe it's time to bump it up to an even 128.
500+ comments and nothing about the fact that in academia, most code that's written for speed (still waiting on that MATLAB code to finish...) is written in either C or FORTRAN? I must have missed something.
Enough times that I've lost count. You probably have too, you just don't realise it.
How many times have you written code like this?
const char* markText = "";
unsigned value = data.unmarkedValue;
if (data.flags & MARK)
{
value = data.markedValue;
markText = " (marked)";
}
printf(" %d%s\n", value, markText);
sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
Actually, you usually want
const char foo[] = "some-literal";
The subtle difference being the behavior of &foo. Why waste any space (even read-only space) for the pointer?
"Antiquated, clunky, and unsafe"
I really hope who ever wrote this isn't a programmer. C is only unsafe when you don't understand how memory works and if you don't understand how memory works you shouldn't be programming. C is only clunky at the hands of an unskilled and amateur programmer who doesn't understand good coding methods and antiquated, well just show me one other language besides ASM that can holds it's own and keep going.
I know someone will try to talk about how OO programming is where it's at and managed code = better code and all that BS, OO languages were invented because people had no F'ing clue on how to write good software. If you can't write it in C then go back and try again. Managed code is the biggest slap in the face because it's extracting the programmer from clean programming. If you honestly want to claim that managed code or OO code is better then good old C then do me a favour and NEVER program again because I can promise you that the crap you input to an IDE is so poorly structured and programmed it should be used for house mats and not actual hardware.
Correct. How are you supposed to write a short CRC-calculating routine without access to the carry flag? (or, and I'm looking at you nvidia, a multiprecision integer library)
Function arguments are an awkward case: the extra 'const' becomes part of the function signature, even though it's irrelevant to the caller. It's understandable (and idiomatic) to spare an API user the distraction.
The purist in me would like a language feature for declaring stronger const-ness of an argument within the function body.
Likewise for Java ('final' keywords in public method signatures).
Don't get me wrong, I think C will have a very long and robust life: It's the one and only bootstrap language of choice offered by just about every OS and CPU maker. And I think that it's too bad.
Many of the reasons for wanting to discard C have nothing to do with the low-levelness of C. Dependencies in C are a nightmare to trace, and probably bloats compile times by a tremendous amount. Then there are deadly designs such as C-strings and even worse inconsistencies within the string functions (think null terminator).
A better-designed system language is certainly possible (e.g., Google Go which is dying a slow death,) and it wouldn't be the worst thing to happen if it were to catch on.
I like C. I also drive a car with a manual transmission, and change my own oil, spark plugs, and brake pads.
Regrinding transmission gears or building carburetors is like programming in assembler (or maybe even writing machine code with a hex editor).
However, that's not to say that I don't also like high-level languages. I especially like C# for the clean object-orientation, plus the syntactic sugar (e.g. accessor methods) and operator overloading that Java doesn't have (not a fan of the Microsoftness, though). MATLAB/Octave is really convenient for mathematical stuff, too.
"[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz
That article could've only been written by someone who isn't a coder. If you are a coder and you can't code C then you aren't a coder. Seriously.
C is a great language. It's the AK47 of programming languages - rough, barebones, you definitely need to know how to handle one because it doesn't do all the handholding for you, but you can drop it in the mud, drive a tank over it, pick it up and fire it - and it will fire. None of that 10,000 library dependencies crap.
Learning to code in C - and I don't mean "hello world", I mean a real program with input validation, safe pointer handling and your own memory management - puts you in a great position to write good code in every other programming language.
Basically, people who don't know C are doomed to repeat the same old mistakes. The problem is that most other languages are a lot more forgiving. And thus your errors don't get noticed so easily, until they've accumulated to create a security issue. In C, if your memory handling sucks, you get a buffer overflow and often a hard crash. If you don't handle your input correctly - crash. And so on.
Back at university, when I was the assistent for the C programming course, students hated me for the 100 ways I could make their precious little programs crash. But those who got their code past me had learnt to write safe code, and I'm taking bets that they still do so today.
Assorted stuff I do sometimes: Lemuria.org
My C code works fine in C, C++, Objective C etc.
C is the base for all portable code, unless you want something like Java, which I am skilled in, but never really liked. I prefer Perl og java any day. But yet, much of the syntax is the same, no matter which one of these languages you use. They are all C-like to some degree.
Your "Because" is silly--merely being wrong (which I was not) does not make for flamebait. You have to try to get others to flame you. If anything you seem to be trolling, but if not... ... to ... [step ...], which could easily serve the same purpose with the same flexibility, and it's incredibly easy to imagine similar syntax with the same power as the C version. You're just trying to contradict me here.
* Not always, and not in the case mentioned (which you didn't even discuss specifically).
* VB.NET uses for
* I disagree, and the example I referred to is +5 informative right now.
* Whitespace is not invisible--it is visible in the spacing of other visible text. Your reasoning here is poor, though I know this issue is largely a matter of taste and I was only (and clearly) stating mine.
* They take fewer characters, which is nice, but can you honestly tell me "not (a and b) or not c" is easier to read than "!(a && b) || !c"? [Note: I'm not sure if I got the precedence rules right and I won't look them up.]
* No. There are honestly broken precedence rules, K and/or R has mentioned it; I can hunt for the reference if you want.
* Again, no. It's an easy mistake to make once in a while. It's also easy to miss when debugging and can cause strange errors.
* This was a minor point, but still, your reasoning is poor: "C used to be worse, so you should be happy about the current situation because it's not even worse!" I'm generally fine with it too, though I slightly prefer single comment "characters".
* An example:
C-style:
switch(i)
{
case -1:
++i;
case 0:
++i;
default:
++j;
}
Forgetting the break's results in completely wrong behavior, but the first two cases should be combined into one, which break is useful for:
switch(i)
{
case -1:
case 0:
++i;
break;
default:
++j;
}
And does one include "break" in the last case? Does it matter? (No.) Ruby offers similar functionality that's more intuitive and less error prone:
case i
when -1, 0
i += 1
else
j += 1
end
(The Ruby version is more powerful, actually, since i can be anything and the === methods are used for comparison.) The C version is another example of easy-to-compile-but-harder-to-read-and-potentially-bug-causing syntax, though it translates almost directly into assembly. The Ruby code is slightly (only slightly) more difficult to interpret yet is better in several ways--no clunky semicolons or colons, no break's, the multiple identical cases have one line instead of two keeping parallelism intact, there's no need to remember the "default" term (why wasn't "else" used originally anyway? another compiler hack?). Each individual issue is quite minor, but small things add up to make everything around us, and C is no different. Like I said, I dislike the clunky syntax. It was clearly made in the early years of programming and has been improved many times by many people in many ways. We seem to be stuck with it now though.
I think C's originators (or at least the still living one) changed his mind about some of them. From looking at the go language which targets the same programming niche some of these things have been addressed.
The semicolons are implied in most places now (as a side effect it enforces a brace style many people dislike, but happens to be my preference -- so even though I'm happy with C's semicolons this is a borderline positive change for me).
Declaration syntax has been made "more sane", which isn't surprising, and by the time K&R wrote the C book they had already started regretting it (one of the assignments was to parse C declarations into "english", look at what the authors wrote about it).
Go revamped switch (and a lot of the control flow operators).
Some of those changes might just be because computers have gotten a wee bit faster in the last 25 years or so, what constituted a great tradeoff on a computer with a 64K (split I+D) address space and maybe 512K max RAM a clock cycles measured in a few Mhz (oh, and these were multi user computers) is a wee bit different from what makes a good tradeoff now. (semicolons I think wind up here)
Some are likely to be a change they would still have made on the original system. (most of the control flow changes wind up here, likely variable decl too)
I like C, and have used it a lot on and off over the years (and probably will still have to again, at some point) - but recently I've been totally loving programming in Google's Go language: it's just fricking awesome, for so many reasons! :)
I think Go is destined for Good-Things(tm) in the future
Please mod up. I found the quiz similarly irritating. Half of the questions say you got the answer wrong and then say that the person writing the questions was making assumptions that are not true in the general case and you are wrong for not making the same assumptions.
I am TheRaven on Soylent News
What a crock of shit. C is just a different tool for a different job.
When writing business software for Windows desktop platforms you don't want to mess around with pointers, memory addresses or other relatively low level stuff like that. High level languages like Java, C#, heck, even Delphi are far more useful for that and allow for far greater productivity.
Sure, there are situations where C is the better choice, just like even lower level languages are sometimes a better choice, but claiming that people choose Java, C# or Python over C because they're ignorant is ignorant in itself. If, these days, you choose to build your windows forms application in C, then you're just getting yourself in a world of hurt that could easily be avoided by choosing a different tool (programming language).
There is a big difference from the caller's point of view between foo(char*) and foo(const char*). The former allows modification of the string being passed while the latter does not. This can be important to the caller, and can mean the difference between calling foo("some string literal") and having to copy that literal into a character array to pass.
You can make something more const in a method, if you really want:
If you're using c++, you can also use const references, which won't add any overhead (I don't think these have been added to the C spec, but I could be wrong):
I've done the const reference trick before when I've wanted to call the const overload of a method on a C++ class because I knew the non-const overload did extra work I didn't want it to do (because it was non-const).
"Save the whales, feed the hungry, free the mallocs" -- author unknown
I like C. I also drive a car with a manual transmission, and change my own oil, spark plugs, and brake pads.
Regrinding transmission gears or building carburetors is like programming in assembler (or maybe even writing machine code with a hex editor).
However, that's not to say that I don't also like high-level languages. I especially like C# for the clean object-orientation, plus the syntactic sugar (e.g. accessor methods) and operator overloading that Java doesn't have (not a fan of the Microsoftness, though). MATLAB/Octave is really convenient for mathematical stuff, too.
And I think that's a very good attitude. :)
It's easier to be a result of the past, but more fun to be a cause of the future! http://www.spacefinancegroup.com/
I have one
char*f="char*f=%c%s%c;main(){printf(f,34,f,34);}";main(){printf(f,34,f,34);}
I feel exactly the same about Scheme. Haven't done a lot in it for production use, but learning it has definitely made me a better programmer!
Later I discovered that there were instructions before the quiz telling the user to assume the x86 and x86-64 ABIs. But I didn't knew this because after I had clicked begin, the instructions disappeared. And no, I'm not about to go buy an x86-64 PC just to complete a quiz that a Slashdot user linked.
I would not say that C is a "great" middle ground. Ambiguous statements are not a requisite of a small language. Allowing pointers to be used uninitialized is not a requisite either. Allowing a non-void function to have no return statements is also not a requisite. There is no legitimate reason for any of the above, they only create problems and make debugging harder. We should not be relying on compiler warnings (non-standard), we should have a language that does not allow us to do things that never make sense.
Palm trees and 8
Generally there are two options when your allocator gives you NULL; that's either retry or abort
Ideally, the program would free up some memory . But you mentioned "Abort" and "Retry" which make up two-thirds of an old MS-DOS-era meme, the third of which is "Fail". There is a way to "Fail" using C++ exceptions, and there is a way to "Fail" using result codes (which is what DOS did). "Fail", propagated up the call stack, would allow freeing up some purgeable resources so that the outer loop can "Retry" later. The other option would be to "Retry" immediately after purging some purgeable resources within the allocator, but I don't know how much latency that would introduce.
I know nine programming languages, seven of them fluently. I also know the machine language of five different architectures, plus the microcode of a sixth architecture.
C is the seventh high level language I learned. I've been coding in C since about 1987. For any serious work, C is my only choice.
If you don't have the discipline or intellectual ability to code well and quickly in C and to produce code that is very nearly bug free on the first pass, you should go back to visual basic (or to other simpler languages) and leave the hard tasks to the pros.
Circle the wagons and fire inward. Entropy increases without bounds.
...I still don't particularly like C, mostly because I find the syntax clunky. Specifically...
* Semi-colon line endings are stupid--they serve little purpose besides making compilers easier to write
It's more than just for stupid compilers, otherwise a newline would serve that purpose as it does in other languages. Sometimes I like writing multi-line single statements (e.g. a function call with huge parameter count) and not have to conversely write a special character to denote a line continuation after carriage return.
* for (...;...;...) syntax is less intuitive than eg. VB.NET's "for a = 1 to 10" or numerous alternatives
Perhaps if you limit "for" to linear iterations. I kind of prefer the "for (init;true;post) ..." format as a clearer "init;while(true){...;post;}"
* declarations are unintuitive (and complicated; see post above for example)
True, #define, typedef, standard declares mix me up sometimes.
* I'm not fond of curly braces--I like Python's indentation better
I'm with you on this, if you want everything on its own line.
* Why make logical operators symbols instead of words?
The same reason mathematical ones are symbols, I suppose. It was logical ;) Real-world match actually uses symbols for logic as well.
* operator precedence can be unintuitive
There is a PEMDAS going deeper to include logic. Use parenthesis to make it stupidly clear if unsure.
* = vs. == causes bugs (many languages have the same trouble though)
Only for those coming from different-styled languages. The = as both a value assign and zero/nonzero check has come in handy many times, and shortens code both visually and compiled.
* comments (//) use two characters instead of one
Can't argue that. C and SQL are the only langs I can think of with double commenters.
* switch's use of break is worse than eg. Ruby's case statement with commas
(I have other issues, like disliking how many mundane details you have to specify in C compared to other languages, but you need a language like C for certain tasks and it'll need lots of mundane details to translate almost directly into assembly anyway.)
What's wrong with the break statement in switch? I like the comma listing cases over multiple stacked cases.
from 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
to 45 2F 6E 40 3C DF 10 71 4E 41 DF AA 25 7D 31 3F
From the page you linked: "This will likely fail fatally. Standard containers deal with memory using allocator (by default standard allocator) and at least one of them expects exception to be thrown when there is no memory and will not check for NULL return value." I mentioned that earlier.
And the funny thing is that most people who write const char* foo really want char const * const foo. You don't want either the pointer or the data pointed at to change. However, almost nobody knows that, so even those who do just use the weaker const char* so people understand the code.
Hmm. I wonder why there's so much animosity towards C? It's a mystery.
Animosity is there because programming in C requires a non-lazy mind, to understand side-effects and items your function will not cover.
There is no framework as one finds with C++, Python, C## or other oo languages.
Leslie Satenstein Montreal Quebec Canada
Ok, here ya go:
case i; when -1, 0; i += 1; else; j += 1; end
It's more than just for stupid compilers, otherwise a newline would serve that purpose as it does in other languages. Sometimes I like writing multi-line single statements (e.g. a function call with huge parameter count) and not have to conversely write a special character to denote a line continuation after carriage return.
A lot of modern languages have implicit line continuations, like Ruby where if you end the line with some sort of operator (or comma) it's implicitly continued. It seems to work very well. (Conversely, a lot of modern languages have an "end of statement" character allowing you to put multiple statements on a single line--in Ruby it's the semi-colon.)
* for (...;...;...) syntax is less intuitive than eg. VB.NET's "for a = 1 to 10" or numerous alternatives
It seems I should have been clearer. VB.NET's full syntax is "for [var] = [bound] to [bound] step [num]", which could easily be hijacked to replace the C "for" syntax without any loss of power. Many languages also offer "for [object] in [array/tree/iteratable thingee]" syntax built-in, like Ruby, Python, and C#. There's lots of good one can do with good "for" syntax.
[Question: Why make logical operators symbols instead of words?] The same reason mathematical ones are symbols, I suppose. It was logical ;) Real-world match actually uses symbols for logic as well.
I'm actually a mathematician with a CS background. In math functions are traditionally denoted by a single symbol (eg. the gamma, theta, or zeta functions; f(x), g(x), h(x), etc. for arbitrary functions in proofs); the only exceptions I can think of are the trig functions, though most likely that was because the names hint at their relationships (eg. csc vs. sec: "co" means you swap the legs in the definition, so eg. sin = opp/hyp, cos = adj/hyp; co is the substitution opp <=> adj). In any case, things are different in computers where full names are allowed. Beyond tradition, making an obvious distinction between bitwise and logical boolean operators is laudable (when I get back to C-style I'm always slightly unsure at first if I should | or ||, for instance).
There is a PEMDAS going deeper to include logic. Use parenthesis to make it stupidly clear if unsure.
For instance, "x & 1 == 0" is actually "x & (1 == 0)" while one almost surely means "(x & 1) == 0".
Only for those coming from different-styled languages. The = as both a value assign and zero/nonzero check has come in handy many times, and shortens code both visually and compiled.
I agree it's useful. I just also say it causes bugs sometimes. I'm honestly not sure if there's an alternative I like; Python and Ruby both continue the C style. I maybe like "is" for "==" but I'm not sure....
What's wrong with the break statement in switch? I like the comma listing cases over multiple stacked cases.
I gave a more complete explanation at the end of this post.
I did an experiment with gcc, and apparently the following is fine in C after all:
extern char *my_strncpy(char *dest, const char *src, int n);
char *my_strncpy(char * const dest, const char * const src, const int n) { /* ... */
}
This trick doesn't work in C++, which considers this as two distinct overloads.
I was also wrong about Java - the 'final' keyword can be added to or removed from argument declarations freely, without affecting the method signature or Javadocs.
It'd be a wonderful language that does prevent all of these things without sacrificing the ability to do something because you do in fact know better than the compiler. I disagree with you about relying on compiler warnings. Use -Werror and get used to it. Use a lint utility and develop good coding habits. It's not impossible to write solid code in C, and it's not (much) harder to do than in other languages, either. With the exception of ambiguous statements which I agree with you on, -Werror takes care of a lot of the "duh" problems, and decent code reviews take care of stupid logic, which is a problem in any language.
If you think correctly defining your function arguments' types is a pointless gotcha, you shouldn't call yourself either one, at least not in C. Maybe you think details like this are beneath you, and maybe you're right and this kind of thing should be abstracted away, but when you get right down to it, computers are just billions of on/off switches, and software has to be written at this level at some point to enable your high-level magic. If they don't get it right, your magic isn't possible. Did you think Python just sprang from the ether?
<xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
Hmm. I wonder why there's so much animosity towards C? It's a mystery.
No it isn't. C is the language of ignorant, self-taught hackers*.
C++ is a far, far better language but it requires sitting down and studying to use it properly. Hacking away at it won't do (well, ok, you may get there eventually but you could save a lot of time by sitting down for a few weeks and studying).
(*) With one exception: There's platforms where C++ is a bad choice because of very restricted target platform or rotten C++ compiler on a particular platform. These platforms are getting very thin on the ground though so this is rarely a good excuse these days.
And no, C isn't 'more efficient'. Not since the 1990's...
No sig today...
Why is that a good thing, or at least why is it worth it relative to the potential for errors and confusion?
Confucius say, "Find worm in apple - bad. Find half a worm - worse."
On the same note, you sound like the kind of programmer who has an ego - the worst kind you can deal with. The kind who will reimplement the wheel, because they think they can do better than a HashMap or a binary search, and cause massive budget overruns on projects. The kind who throws every design pattern possible at a problem so their code confuses others, and makes it extremely hard to maintain or change.
I'm not saying Python is better for a business application than C. I'm just saying that for each problem, there is a tool. And there are situations where Python probably would offer some advantages over C and vice versa.
You seem bitter.
Maybe my statements were a bit bold and lacked the required subtlety, but you're making a completely incorrect assessment of me. I'm dealing with C often enough, but there are a lot of situations where using a language like C# or Java is the logical choice.
Such languages won't always allow for greater productivity, sure, but in one case it does and in another it won't. You almost seem to have some sort of animosity towards C# or Java, throwing basically anyonethat is using or preferring these languages over C on a "newer programmer" pile who aren't worth the air they're breathing.
Once again: all I'm trying to say is that in some situations you're better of using a language like Java or C# and in other situations you're better off using a language like C. Again other situations are better handled by PHP or ASP.NET. Choosing the right tool for the right job. That's all this is about. And anyone saying that the world is black and white where C is always better or where Java is always better is just not seeing things right.
Object Oriented Programming is, by far, the more ideal way to develop modern software. Encapsulating data and responsibilities in a class is preferred over spreading responsibilities across many files.
People who prefer C over C++ simply don't get OOP, period. They strain to identify the purpose of classes and encapsulation and thus assume it is not required. They are not "modern" developers, they are stuck in an era of procedural coding and have not crossed the threshold into viewing code as a collection of interactive components with specific responsibilities and structured data.
Yes, C has its purpose if you are looking to build a quick and dirty library of procedures, but given that C++ is a super-set of C, there is no reason NOT to use C++ in favour of pure-C. The modern computer is highly multi-threaded and has more power and memory then the originators of C had ever envisioned. The added overhead of virtual tables and other class based mechanisms is not a significant reason NOT to use an OOP language. If I had a developer that toiled in pure-C and claimed that they were doing so for performance reasons, I would fire them on the spot.
C is the basis of many languages and scripts, there is nothing wrong with the C Language, but the problem of a lack of OOP development I can't get over. I have never seen a C library that wasn't a sprawling mess of haphazzardly organized procedures and structs. There is little capacity to Unit test C, there is little capacity to apply pattern development in C, there is little opportunity to multi-thread C. C libraries become black boxes of untouchable code, prone to significant defects and non maintainable. C's limitations make it a dinosaur captured in tar and turned into a fossil.
Anyone claiming that pure-C development is superior to OO development is not a good developer, period.
I haven't thought of anything clever to put here, but then again most of you haven't either.
If I need to know the details, I'll Google it. I understand your point, especially when talking about a language as prevalent as C. However if you think anyone knows every language ever invented, you're mistaken. And given the stuff that's being taught as CS in colleges currently, expecting someone to know a language detail from a language they may never have worked with might end up filtering out some of the best engineering talent. My 2c.
Of course somebody who isn't a C programmer shouldn't care about this. Both the previous poster and I were talking about C programmers, which is pretty clear from our posts.
I can't decide if that detail escaped you, or if you're saying somebody hiring a C programmer should hire somebody that would need to google this kind of thing.
<xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
C was the first programming language I ever encountered in the era of programming. I still like it for its simplicity, speed, and compatibility with its counterpart, C++. I'm not saying that it's the best or worst programming language that everyone must learn or hate, but I just say that whatever keeps you happy in programming is the one for you, generally speaking.