4 ms·
These facts is not a lies. They are inconviniences which one can see looking on C from perspective of higher level language. But if you learn how to program wit
by ordu 10y ago
These facts is not a lies. They are inconviniences which one can see looking on C from perspective of higher level language. But if you learn how to program with assembler before studing C, than all these facts would look like obvious and convinient syntactic sugar.
Maybe in C++ these facts become inconvinient, because of C++ pretending to be higher level language than crossplatform assembler. But if it is a problem, it is not problem of C, it is problem of C++.
- gpderetta 10y agoNone of those 'lies' have anything to do with assembler. C deviated from regularity for the sake of convenience in some cases, and now we are stuck with those bad decisions forever.
- ordu 10y ago> None of those 'lies' have anything to do with assembler. They do. Lets take a look at the very first one. "Array name is just a pointer". Assebler "array" is a name of a label. So its just named address in memory. Or we can alternatively say, that assembler array is constant pointer. `sizeof' returns size of array in bytes? Hmm... maybe that because main C abstraction for memory is the assembler one: memory is a continuous sequence of bytes? `sizeof' meant to be used for functions like malloc or memcpy, not for operator `new'. When we use some dynamic memory allocation in assembler we get pointer to untyped memory chunk, compare with C: void* malloc(size_t size); If you wish I can show you the connections of other 'C lies' with assembler abstractions. I'm too lazy to write about all of them, but I could write about one more if you ask. Just pick one you like more. > now we are stuck with those bad decisions forever Yes, you are right. We stuck with that. And it is bad. But it doesn't make my point wrong. C is crossplatform assembler, and these decisions looks pretty good from perspective of assembler. They give to programmer low level control on generated machine code while keeping code portable, and its very useful in some cases. For example when you developing an OS kernel.
- gpderetta 10y agoFrom an assembler point of view a structure of N elements of type T and an array of T[N] have exactly the same layout and are accessed in exactly the same way [1], but in C have wildly different semantics. Sizeof behaves exactly the same way for structs and arrays, so it is one of the few things in C that treat arrays "correctly". [1] although usually the offset is constant for a struct field access.
- ordu 10y ago> but in C have wildly different semantics. Can you show it with example? I'm not sure what you mean exactly. Look: struct { int a, b, c; } foo; int *pfoo = (int*)&foo; printf("%d, %d, %d\n", pfoo[0], pfoo[1], pfoo[2]); Code like this can have problems due to alignment, but at my opinion its not "wildly different semantics".
- gpderetta 10y agoIn addition to being UB, the example doesn't illustrate the issue: arrays in C are not first class as they can't be passed by value and can't be assigned. The decay-to-pointer thing that prevent this regularity has nothing to do with asm.
- ordu 10y ago> In addition to being UB, Yes, its UB. But I'm not persuade you to use this UB in real code: in real C code use offsetof from stddef.h. The only thing I want to say is: this code would work everywhere (if you pay attention to alignment). And its not coincidence by some chance: C mimics asm, because C needs to be 100% predictable to coder. Because asm use simpliest and the most obvious abstractions, with predictable runtime costs. C also goes this way. So its inevitable for my code to work. With some precautions, but it would work everywhere. > the example doesn't illustrate the issue... Yes, I suggested it, and I asked you for some illustrative example, because I can't understand your reasoning from "arrays are not first class" to "nothing to do with asm". I see it other way: "arrays are not first class" is "asm mode".