Live data from Hacker News

A convenient untruth: Array notation in C is a lie

blog.feabhas.com

61–70 of 176 posts

Re: A convenient untruth: Array notation in C is a lie

#61
post #16

Earlier quoted context omitted.

No, C (and C++) is used as much as ever Is this really true, especially for C? Lots of things that used to be done in C is today done in C++ and lots of things that used to be done in C++ is today done in Java or C#.

In the embedded world, the default language is still C by a wide margin. You have to argue hard to have C++ considered and languages like Rust&Go just aren't on the radar. Only in HN world is C considered legacy. For the rest of the world, its the well-known workhorse of the software world.

I can confirm that. I write C for embedded systems every day, but for better or worse, I don't see any replacement for it in foreseeable future. C++, Python, Java etc. might be used at higher levels (GUI, for example), but all the guts are still good, old, plain C. Rust is still in its infancy so it's hard to tell and even if it succeed, it will be evolution, not revolution and will take decades to replace C fully.

HN is a bit of echo chamber as mostly SaaS, web and other high level application developers are here. For them C might be dead as well, but if you have anything to do with hardware and system programming, C is still the tool.

Re: A convenient untruth: Array notation in C is a lie

#62

Earlier quoted context omitted.

I don't agree with: int[5] arr; being a more readable syntax. The problem is that if you later have: int[7] arr2; It would make sense that arr and arr2 are different types (as the thing on the left is different) while they are the same type and you should be able (hopefully!) to use them as arguments to the same function. On the other hand I agree that: int* arr; makes more sense than more commonly used: int *arr; al…

although it's messed up anyway as But that's because they wanted it to be like that. To me, this code is very unclear: int a, *b, c, d; because everywhere else, multiple declarations in one statement all have the exact same type, but for some reason pointers get special treatment so that you can declare variables of type X and variables that are pointers to type X in the same statement, which just seems odd to me. I'…

I'd say it's better style anyway to only ever declare multiple primitive types in the same statement.

Re: A convenient untruth: Array notation in C is a lie

#63

C now has static array indices. For example void func(int arr[static 8]) {} imposes a limit on the size of the array that can be passed as an argument (you cannot pass an array of 7 or fewer elements.) I'd suggest that to the author, but given the article, I fear it may give him a heart attack.

What version of C is this in? And do modern implementations (clang, GCC) adhere to it (without extensions)?

It's a feature added in C99. Both clang and GCC do support it, assuming -std=c99 or later

Re: A convenient untruth: Array notation in C is a lie

#64

Earlier quoted context omitted.

> I will now duck and get far away from the internet, in fear of all the hateful comments explaining to me how I am wrong, and apparently just don't understand the superior beauty of complicated C syntax. I am going to be that person :-) One phrase – "declarations mirror use". In a declaration, you use the same set of operators around the declared object that you would use in a normal expression. All of these operato…

I think if all type-information were kept together, it might read simpler: char*[X] arr; You read strictly left to right: char pointer array of size X called arr. Basically, it takes a simple type (char in this case) and for each thing to the right, wraps it in something. You could read it as: given a char, we have a pointer to it, and an array of size X of these pointers. It would be interesting if the use did "mirr…

> You read strictly left to right

That wouldn't play well with pointers to arrays and pointers to functions:

    int (*pa)[X]; // int(*)[X] pa;
    int (*fp)(void); // int(*)(void) fp;
Here is how I designed the type declaration syntax in my own language, Quaint (https://github.com/bbu/quaint-lang):

    pa: ptr(int[3]); // int (*pa)[3]
    fp: fptr(): int; // int (*fp)(void)
    arr: int[5]; // int arr[5]
    p: ptr(int); // int *p
    pp: ptr(ptr(int)); // int **pp
    arrp: ptr[5](int); // int *p[5]
You basically have the identifier first, and then a recursive expression which uses mostly function-call-like expressions in order to nest recursive types.

Re: A convenient untruth: Array notation in C is a lie

#65
post #2

It's not that convenient an untruth seeing as these are probably some of the first things you learn in C, and some of the first gotchas that'll getcha. Having said that, the article was well written.

I think it's more likely the reaction to someone who uses magic languages that perform complicated actions over a simple assignment. If you think of C as a high-level assembly language whose assignment instruction is converted into a single machine instruction, this type of behavior is not so surprising.

> I think it's more likely the reaction to someone who uses magic languages that perform complicated actions over a simple assignment. If you think of C as a high-level assembly language whose assignment instruction is converted into a single machine instruction, this type of behavior is not so surprising.

C assignment isn't that simple. Consider this program:

    #include 

    struct point { int x; int y; };

    int main(void) {
        struct point p1 = { 0, 0 };
        struct point p2 = p1;
        ++p2.x;
        printf("(%d, %d), (%d, %d)\n", p1.x, p1.y, p2.x, p2.y);
    }
It prints "(0, 0), (1, 0)", as most people would expect. C isn't as transparent a layer over assembler as some people like to imagine; it just doesn't have first class arrays.

Re: A convenient untruth: Array notation in C is a lie

#67
post #5

Earlier quoted context omitted.

What is "mainstream" these days?

React (a javascript library, sometimes referred to as reactJS or react.js) and more specifically its most popular module, Reagent, which is a full, lazily-loaded preemptive operating system that can run concurrent Java, Pythonjs, Rubyjs programs all from your browser while allowing cooperative suspend, load and save to network or local storage, intertab cooperative process management, etc. Basically, if you're not wo…

You laugh, but Odoo* 's hand-rolled, Backbone.js-based frontend framework includes an interpreter for a subset of Python. They call it py.js. I'm not fucking with you.

https://github.com/odoo/odoo/tree/10.0/addons/web/static/lib...

Just so that you can experience the full horror: Yes, the Python server ships XML templates with raw embedded Python code to the client. The client then parses the XML and interprets the Python using this py.js thing.

If the embedded Python needs to access the database (and it almost always does), the client makes calls to a JSONRPC interface on the server.

(If you ever think of using Odoo. Don't. Just... don't.)

*An open source ERP.

Re: A convenient untruth: Array notation in C is a lie

#68

Earlier quoted context omitted.

I don't agree with: int[5] arr; being a more readable syntax. The problem is that if you later have: int[7] arr2; It would make sense that arr and arr2 are different types (as the thing on the left is different) while they are the same type and you should be able (hopefully!) to use them as arguments to the same function. On the other hand I agree that: int* arr; makes more sense than more commonly used: int *arr; al…

although it's messed up anyway as But that's because they wanted it to be like that. To me, this code is very unclear: int a, *b, c, d; because everywhere else, multiple declarations in one statement all have the exact same type, but for some reason pointers get special treatment so that you can declare variables of type X and variables that are pointers to type X in the same statement, which just seems odd to me. I'…

> [...] everywhere else, multiple declarations in one statement all have the exact same type, but for some reason pointers get special treatment so that you can declare variables of type X and variables that are pointers to type X in the same statement, which just seems odd to me.

It's not just pointers:

  int a, *b, c();

Re: A convenient untruth: Array notation in C is a lie

#70
Worth noting: since everyone on HN is clearly an expert on C[1], we're just as clearly not the audience for this post. It's obviously written for people who haven't learned this yet, who might still be fooled by the superficial similarity of arrays in C to arrays elsewhere (or to what any rational non-lazy person not implementing their first compiler might expect). That doesn't make it a bad article, so stop being so gratuitously negative. It's actually a pretty good explanation, for somebody at that level, of how C arrays can trip you up. I might use it myself, as a reference for some of the people I mentor. Pedagogy matters.

[1] Or any other topic. Just ask any one of us. Apparently we all sprang fully formed from Athena's brow, already endowed with every bit of knowledge we'll ever need.

Post reply on HN