Many have this opinion. Somehow, by doing manual memory management allocation and garbage mangement one would become a better programmer.
I have little experience in C mainly because I can write terser and more readable code in Racket or Haskell. However I'm willing to give C a try just to learn these lessons that everybody keeps talking.
But I have a sneaking suspicion that I already know most of what is there to know. Can you list some useful lessons that a typical high level code dweller would be oblivious of?
Name:
Anonymous2012-09-02 6:20
C is like a portable assembly language. The point of it is to be very near to the hardware, without having to do manual register allocation. If you were to write a kernel for example, you would want to keep the cycle count low and the (non-hardware related) interrupts minimal, hence Haskell would probably be a bad choice; but C would be great for it.
Manual memory management doesn't make you a better coder though, it's just useful for a lot of things.
Manual memory management doesn't make you a better coder though
It does. By forcing you to think about how much memory you use, and explicitly allocate/free, it gives you better understanding to reason about how you should use memory. You're less likely to do stupid things like making copies of data that weren't needed, or keep around memory that should be freed.
It's easy to see this in code written by ex-Java programmers who have migrated to C++. Object copies and new everywhere.
Name:
Anonymous2012-09-02 6:44
Is learning C really a must for a programmer?
Nope. There are only two eternal languages: machine code and Lisp.
C/C++/Puthon/Java are required only if you want to deal with the faggots. It is like you have to love buttsex to join gay community.
The most important thing about C is that it works everywhere. Every language has a C API. Every OS and architecture has a C compiler. It's versatile, portable and powerful.
C is to programming langages as English is to natural languages.
Name:
Anonymous2012-09-02 6:55
>>7 if it is popular, it must be good
kill yourself, cocksucker.
They just propagate that thought because they can use it as a defense against explaining having to spend more time rewriting/optimising what didn't work out the first time they wrote it, and thus earn more for doing less.
Name:
Anonymous2012-09-02 6:59
>>8
Well, have fun writing trivial fizz-buzz-esque programs in your toy language.
You don't need to learn C for that. Any decent language will quickly develop conventions of what is good practice and bad practice depending on compiler implementation.
Name:
Anonymous2012-09-02 7:03
>>11
It is. While English is popular, it is ugly and rigid, compared to Slavic languages.
Name:
Anonymous2012-09-02 7:05
>>10
I'm so happy degenerates like you dont use my language.
Name:
Anonymous2012-09-02 7:07
>>13
Yeah, but nobody speaks those languages but slavshits.
And nobody wants to talk to them.
>>16 Back to /int/, ``comrade."
You're mistaking me with commie Jews, Hymie.
Name:
Anonymous2012-09-02 7:16
>>17
And then again, the less outside filth speak my language - the better, because language is a scared property of the nation - the consciousness of the nation. That is why I'm scared for Japan, when so many weeaboo niggers strive to learn Japanese.
Please stop derailing threads or spawning irrelevant threads.
Name:
Anonymous2012-09-02 7:29
>>17
In my home country, this is Kazan of Russia, jewish student
1. control stuff everything
2. bribingto policeman
3. spit to intelligence when talking, soul smell bad
4. have too much money, many jewish student, armani cloths and versace pants, testoni shoes
5. raping? russian girl because russian girl say jewish boy no thanks, very big nose and greasy
6. very smell of falafels eating by jew
7. very smell of colonization, no leaving long time, sometime 1000 years?
jew=devil same
Name:
Anonymous2012-09-02 7:31
>>22
Awful. You should learn you Hebrew and leave for Israel.
And how is that supposed to help your case? It perfectly illustrates your fallacy. Slavic languages might have better
theoretical grounding but in practice their value compared to English is insignificantly small because nobody uses them for anything significant.
Nobody said that C had the best theoretical grounding but rather that it is supported everywhere.
This is programming we are talking about here. If you can't be pragmatic about things you don't belong here.
>>24 And how is that supposed to help your case? It perfectly illustrates your fallacy. Slavic languages might have better
theoretical grounding but in practice their value compared to English is insignificantly small because nobody uses them for anything significant.
English is easy to learn but hard to use. Slavic languages are hard to learn but easier to use. So yes, nobody will ever use Slavic languages beside Slavs. Of course there languages like http://en.wikipedia.org/wiki/Ithkuil which are even more flexible than Slavic, but they aint free and you wont get one as a birthright.
C is the 70's Java, sponsored by Bell labs to fit their programmers. Pascal also has static types, inline asm, pointers and manual memory management, but...
you should learn C and write one super fast application that does something non trivial and never calls malloc once. Simulations and 3D physics engines are always a good choice. Allocate all of your dynamic data in global statically allocated memory pools. Do not use any data structure other than arrays and spacial trees. Make minimal use of polymorphism. Try to get the game play as smooth as possible. Finally, once the simulation is finished, introduce a FFI for it from racket and then make complex AIs for it. Sound good?
Name:
Anonymous2012-09-03 19:43
>>40
Polymorphism in C?
Are you tossing void* around?
>>45 Comeau C/C++ 4.2.45.2 (Apr 12 2001 10:06:52) for xxxx
Copyright 1988-2001 Comeau Computing. All rights reserved.
MODE:strict errors C90
"fuckyou.c", line 1: warning: type qualifier on return type is meaningless
const int* const (*(*(*foo)(void** (*)(const char*(int**), short int*(void(void)), volatile void* (*)(int*, const volatile int(void*(void), const long**[128]), char[32])), int, const char* [5]))(long long const*** (*[5])(), short))[3];
^
"fuckyou.c", line 1: error: the type "long long" is nonstandard,
Consideration: Use --long_long for this to work in strict mode
const int* const (*(*(*foo)(void** (*)(const char*(int**), short int*(void(void)), volatile void* (*)(int*, const volatile int(void*(void), const long**[128]), char[32])), int, const char* [5]))(long long const*** (*[5])(), short))[3];
^
1 error detected in the compilation of "fuckyou.c".
Somehow, by doing manual memory management allocation and garbage mangement one would become a better programmer.
Why would you start that sentence with "somehow?" If you can't see how learning memory management (I think that's what you were trying to say) makes you a better programmer, then maybe programming isn't your bag.
Name:
Anonymous2012-09-04 3:39
>>47
Shut up buttburger. Clearly he is just using that because he lacks confidence in his own opinions and seeks reassurance from the prog community
>>35
Knuth's quote is about premature optimisation, but optimisation is never premature, so it's like saying "if the moon is made of cheese, it must be cheddar".
Have you read through the entire TeX source code? I bet a lot of programmers today would say that the entire thing is "premature optimisation" and a TDWTF. If I remember correctly, there isn't a single instance of dynamic allocation, it's one huge monolithic application.
Name:
Anonymous2012-09-04 4:37
Most people recommend learning C because it teaches you the fundamentals of programming in a strict environment & stops a lot of people from pursuing programming as a career. If you can't handle simple C coding, you'd only be a burden to whoever hired you for anything serious.
A couple years ago, I took an intro C course in college for EE (I just needed the credits) and I've never seen so much anguish. Pointers ruined hipster dreams. Empowered womyn cracked under the pressure of structs. The ubernerd who decided to bring his tank-like gaymen laptop everywhere couldn't figure out how to SSH to compile his helloworld that wasn't going to run anyway. Absolutely delicious Schadenfreude.
>>50 there isn't a single instance of dynamic allocation, it's one huge monolithic application.
What are you implying here? Is it merely an off hand comment?
Name:
Anonymous2012-09-04 9:05
Cudder thats crazy talk, some optimizations are obviously premature because other optimizations should precede it in priority.
TeX source code ... TDWTF.
( ≖‿≖)
If I remember correctly, there isn't a single instance of dynamic allocation
Well, sorta...
@* \[9] Dynamic memory allocation.
The \TeX\ system does nearly all of its own memory allocation, so that it
can readily be transported into environments that do not have automatic
facilities for strings, garbage collection, etc., and so that it can be in
control of what error messages the user receives. The dynamic storage
requirements of \TeX\ are handled by providing a large array |mem| in
which consecutive blocks of words are used as nodes by the \TeX\ routines.
Pointer variables are indices into this array, or into another array
called |eqtb| that will be explained later. A pointer variable might
also be a special flag that lies outside the bounds of |mem|, so we
allow pointers to assume any |halfword| value. The minimum halfword
value represents a null pointer. \TeX\ does not assume that |mem[null]| exists.
Does Standard Pascal really not have dynamic memory or was Knuth aiming to get TeX working on microcontrollers?
>>62
Already done, it's called gcc. It might be bloated shit but at least it works virtually everywhere.
Name:
Anonymous2012-09-04 22:05
>>64
GCC is ugly as your fat yiddishe mama. And it is very hard to configure GCC for crosscompilation.
Name:
Anonymous2012-09-04 22:09
>>55
Using only static allocation with (or without) the stack is very common in memory constrained environments, as it ensures that memory usage will never grow past a hard limit or become fragmented. As an example, the Mars Curiosity Rover was developed according to the JPL C coding standards, part of which includes basically forbidding dynamic memory allocation in order to eliminate allocation failure-related bugs.
A common tool used in these environments is a "memory pool", basically a statically allocated chunk of memory that you can allocate and destroy (usually) fixed-size objects within. Consider a program that needs to allocate and destroy hundreds of tiny objects per second, at unpredictable intervals. Rather than using standard malloc/free and fragmenting the fuck out of your memory (similar to the situation on a disk, memory fragmentation can quickly lead to a situation where you have enough memory available to allocate something, but because there aren't any contiguous free regions large enough, the allocation fails), you statically allocate ("set aside") enough space for a few hundred of those objects and let a memory pool library handle allocations within the pool.
>>56's quote makes it sound like a ridiculous practice ("who would write their own memory allocator for a typesetting program?"), and iirc even Knuth regrets some of the technical decisions he made when developing TeX, but I'm sure it made more than enough sense back in 1978.
>>4 It's easy to see this in code written by ex-Java programmers who have migrated to C++. Object copies and new everywhere.
Aren't ex-Java programmers more likely to pass pointers by value, since it's roughly equivalent to a Java reference?
It might be a matter of awareness of the meaning of the syntax.
Name:
Anonymous2012-09-04 22:56
Let's say based on a decision, I may have an array of strings that has to hold either 10, 100, or 1000 strings.
Wouldn't it just make sense to dynamically allocate that memory? Or would you really have me believe that the best course of action is to allocate room for 1000 strings and only use 10 if needed.
The dynamic memory allocation functions return error values if they fail. So what excuse do you have to not use them, unless you're a moron who doesn't check?
void fill(char **array, int n) {
int i;
for (i=0; i < n; i++) {
array[i] = "HAX MY ANUS";
}
}
int main() {
char** array;
switch(rand() % 3) {
case 0:
array = allocate10();
fill(array, 10);
break;
case 1:
array = allocate100();
fill(array, 100);
break;
case 2:
array = allocate1000();
fill(array, 1000);
break;
}
}
Name:
Anonymous2012-09-04 23:33
>>70
you really need more information on the problem to make a proper decision.
If non of the strings will escape the body of the function, every single one of them can be allocated on the stack. With this you will have trivial allocation and deallocation, giving good performance, and there will be absolutely no fragmentation, giving good memory use.
If all of the strings will persist throughout the lifetime of the program, and their values are known at compile time, they ought to be statically allocated and constant.
If the strings really need to have dynamic extent, then you have a few options. One is to use the malloc free interface, in which you ask for a block of memory of an arbitrary length, and a search will find and reserve a block for you until you later release it with free. Fragmentation is unavoidable, and will waste memory. The search for large enough blocks can become expensive once the free space is cut up and crowded by many reserved blocks. Another option is to use a garbage collector. With the freedom to move objects around, fragmentation can be eliminated. Usually there is an additional cost and complexity of the garbage collection traversals, but in the case of strings and other data types that contain no references, they can be reference counted. And then there are memory pools, which are more effective when you are allocating many objects of the same size. With memory pools allocation is trivial and fragmentation is avoidable. But the problem is that strings are not fixed length in general, and the generality of the malloc free interface is more appropriate.
>Or would you really have me believe that the best course of action is to allocate room for 1000 strings and only use 10 if needed.
If the application is ever in a state in which it couldn't handle 1000 strings, and it might happen, then the application is insecure. Even if you handle the error and prevent a segfault, it is still a failure if you can do nothing but gracefully halt the application. You have to do everything you can to prevent this from happening on the platform you are targeting.
The dynamic memory allocation functions return error values if they fail. So what excuse do you have to not use them, unless you're a moron who doesn't check?
I can only assume that you are assuming that the memory allocation function will give the same results in performance and memory use regardless of its interface.
The dynamic memory allocation functions return error values if they fail.
Not on Linux, they don't. Linux will happily tell you that all is well, and then randomly kill unsuspecting processes until there's enough memory available to make it work or until it kills something critical like init.
This topic is still very widely debated even in academia.
Some people say that learning something like C breaks you as a programmer.
Others will say the same about prolog or haskell.
Really, as a programmer, you should have a wide toolset of languages that you are competent in. If you've never used an imperative language before, C could be really beneficial.
At the least you would begin to understand that mindset.
>>73-74 An aircraft company discovered that it was cheaper to fly its planes
with less fuel on board. The planes would be lighter and use less fuel
and money was saved. On rare occasions however the amount of fuel was
insufficient, and the plane would crash. This problem was solved by
the engineers of the company by the development of a special OOF
(out-of-fuel) mechanism. In emergency cases a passenger was selected
and thrown out of the plane. (When necessary, the procedure was
repeated.) A large body of theory was developed and many publications
were devoted to the problem of properly selecting the victim to be
ejected. Should the victim be chosen at random? Or should one choose
the heaviest person? Or the oldest? Should passengers pay in order not
to be ejected, so that the victim would be the poorest on board? And
if for example the heaviest person was chosen, should there be a
special exception in case that was the pilot? Should first class
passengers be exempted? Now that the OOF mechanism existed, it would
be activated every now and then, and eject passengers even when there
was no fuel shortage. The engineers are still studying precisely how
this malfunction is caused.
>>72
You recorded data from a test. There is one file for each data channel recorded. The number of channels typically ranges from 2-250.
You need to compile a list of each channel name which is found in the header of each file. Suppose that the first line of the file is the channel name if you intend of offering some code.
How do you compile an array of strings that has each channel name in order? Go on, offer the best solution. It just seems like a perfect situation to dynamically allocate memory.
Name:
Anonymous2012-09-05 0:31
>>70
I think the point of these embedded safety critical coding guidelines is to make it easy to prove how much memory you're using and knowing that you can guarantee that your memory allocations will never fail since you know the limits of the device it's running on.
Name:
Anonymous2012-09-05 0:35
>>73
They might return an error code, if your demand is completely unreasonable like (size_t) -1. I haven't met a GNU/Linux distribution that doesn't give you an error code from malloc when you do that.
All this being said, I don't think a safety critical device would ever over-commit memory and then randomly kill programs, it's even optional in Linux.
>>85
The JVM is a byte code compiler, it is written in C++.
Name:
Anonymous2012-09-05 1:10
The dynamic vs static debate is kinda pointless. Usually, the use cases where dynamic allocation makes sense usually won't make sense to use static allocation and vice versa. For the two extremes: Media editing applications have to expect handling arbitrary amounts of information but the application can be installed on arbitrarily specced hardware to handle the job. Traditional critical control systems handle fixed sized arrays of numbers with filters, transforms and heuristics applied over it, strings shouldn't even come into the equation here except for a string table, and the software is tailored to specific hardware.
>>68
They tend to pass the whole object as a copy, because the syntax for that is identical to Java's "pass the reference to the object". Only when the realise they need to actually change the object do they (in a somewhat confused state) start putting &s in.
>>78
If I had to write a program to do this I would probably dynamically allocate once, once the number is known. Otherwise... head -n 1 <yourfileshere> | sort | uniq
Name:
Anonymous2012-09-05 5:35
>>66 A common tool used in these environments is a "memory pool", basically a statically allocated chunk of memory that you can allocate and destroy (usually) fixed-size objects within.
This is still dynamic allocation. You might even unknowingly have used a malloc implementation that had a static limit. When the pool is empty you've got an error. Static memory allocation means that all computations are bounded in space. There's no recursion and no variable sized objects (where do you store references to the fixed-size object, in another fixed-size object?). This works fine for a lot of data crunshing where you can work with an independent subset at a time and applications where the dimension of data vectors in the domain are obviously smaller than an suitably chosen number. Sometimes it's also okay to truncate strings that are too long.
Creating your own tailor made custom allocator that returns (usually) fixed-size ranges from a static word_t pool[POOL_SIZE]; doesn't mean you're suddenly allocating objects statically. Yes, you've gotten rid of fragmentation since your allocator knows that every allocation is equally big, and that's an advantage malloc doesn't have. Who'd have thought that optimizing for the special case wins over a general case implementation?
I know, let's all just allocate cons pairs (they're fixed size) and then we can build arbitrarily long vectors and strings by chaining them togehter. It's all statically allocated!
Name:
Anonymous2012-09-05 9:53
>>78
See >>87. If the strings need to persist outside of the function, then some form of dynamic allocation will be useful. But if you are only printing them out in sorted order for example, all of the strings can be allocated with alloca. Furthermore, if it is possible to anticpate the lengths of the strings and their quantity, it is possible for one function to allocate a memory workspace with alloca and then pass pointers to the workspace down to the child functions. The point here is that dynamic allocation isn't always necessary, and there are alternatives that will sometimes give you better performance and memory use. If you are not aware of these alternatives, then you are condemned to writing programs that use more memory or more time than necessary.
>>89
Allocation in a memory pool can always be performed in O(1) time using the same short and deterministic sequence of instructions. The same cannot necessarily be said of your favorite malloc implementation. Malloc's interface is more general and this forces its implementation to be more complex. Malloc doesn't know that you might be allocating and deallocating 1 million objects each of size 36 bytes, several times a second. But you do know this, and you can design a more efficient way to get this memory.
>>89 Allocation in a memory pool can always be performed in O(1) time
This is correct. But hard time requirements is not always the only problem with dynamic allocation. Dynamic allocation (even if it's from a memory pool of constant size chunks) is dynamic, i.e. performed at run-time and it can fail. Static allocation is perfomed at compile time and the bounds are known in advance. A memory pool is not static allocation.
Name:
Anonymous2012-09-05 11:18
>>40
Of course you need to malloc at least once (or you might need to malloc more than once to find out how much you need to malloc if the stack is not enough for that task) to get big memory on the heap, I mean if that's what you need.
But I guess this only will teach you how shitty the von neumann architecture is and then how shitty (presumably)linux handles your memory on the heap. That's not really programming in the purest sense in my opinion, although it is valuable to realize the sorry state of "cutting-edge" computing.
Basically, learn C if you need to know how shitty computing is today, all the nasty mistakes are there for you to see.
Name:
Anonymous2012-09-05 11:32
>>93
If only Intel stuck with the iAPX432 instead of making the 8086, computing might have been 40 years ahead of the 70's instead of 70's technology with more RAM and a faster speed.
>>61
C is nothing at all like assembly. Please stop making this comparison. It is only as portable as are its implementations, none of which btw use more than a small subset of the instruction set without being begged. Fioc could also be compiled and diassembled...that doesn't make it cat all similar to asm programming.
>>95
What do you mean? Objects are not information. There are many good data-interchange formats already. What else do you need but lists, maps, strings and integers?
What else do you need but lists, maps, strings and integers?
trees, booleans, floating point numbers, rational numbers, complex numbers, vectors, matrices, functions...
Name:
Anonymous2012-09-05 18:40
>>101
You could implement trees quite trivially with a map.
>>111
I guess this is listenable if you're completely oblivious to the so called ``chiptune'' genre, however this is really terrible and you should honestly feel bad for liking it.
Makes me wanna puke, the fact that people who post such things invariably have the most awful taste.
Well that's like bits and pieces of rubber and steel in an envelope handed to me, when I wanted a wheel. It would take too long time to put it back together. If you on the other hand knew about the properties and interfaces of a wheel, you'd just hand it to me, not dismantling it first. We'd speak the same language and understand each other living in the same world, on the same terms. Things would be a smooth ride.
It doesn't have to be C, but a language that is lower-level than your Ruby would be good to learn and prevents you from becoming like the average Rails hipsterfaggot.