Live data from Hacker News

A convenient untruth: Array notation in C is a lie

blog.feabhas.com

91–100 of 176 posts

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

#91

Earlier quoted context omitted.

Surely it would still mirror use if the operators were applied to the type, rather than the identifier? Preferring 'char ٭arr[X]' over '٭char[X] arr' seems arbitrary to me. I see no reason the 'declaration mirror use' principle can differentiate between the two. Personally I prefer the latter since it makes it easy to separate the type from the identifier.

'char ٭arr[X]' over '٭char[X] arr' What is this dirt after char and before char? This wouldn't even compile.

HN converts asterisks to italics and I too couldn't find a way to escape them, except when surrounded by backticks `*`. Not a C-friendly discussion forum :-)

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

#92
post #73
post #69

In the last example, > char string[] = "Hello world"; I thought that gives out warning these days. Isn't the proper type of a string literal the following? > const char string[] = "Hello world"; Therefore, you can't really modify individual characters there.

> Isn't the proper type of a string literal the following? No, it's a const char pointer. Your declaration actually makes a copy of the "Hello world" string into a new char array, distinct from the string literal itself: [~]$ cat test.c #include int main(int argc, char ** argv) { char a[] = "test2"; printf("sizeof(a): %lu\n", sizeof(a)); return 0; } [~]$ gcc -std=c99 -pedantic -Wall -o test test.c [~]$ ./test sizeof(…

The type of a string literal is array of char, and like other arrays, they decay to pointers to the first element when used in expression context, with three exceptions: sizeof, taking the address with &, and when used as a string initializer. "test2" in your example is not a const char *, it's an initializer, since this is one of the exceptions to array-to-pointer decay.

http://c-faq.com/aryptr/aryptrequiv.html http://c-faq.com/decl/strlitinit.html

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

#93

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've heard this phrase - "declarations mirror use" many times before but it just doesn't click for me for some reason. Who's use? The compiler's or the programmer's? Can you elaborate? Sorry if this silly question but I've scratched my head enough on hearing that phrase that I thought I would ask. Cheers.

The meaning of "declarations mirror use" is that the programmer can use the declared variable in the exact same way as being declared (by applying the exact same operators):

    int **p; // declares "p" as a pointer to a pointer to int
    int x = **p; // the "**p" expression mirrors the declaration and its type is "int"
This is true even for functions:

    int *f(int a); // declares a function which takes an int and returns a pointer to int
    int res = *f(3); // the "*f(3)" expression mirrors the declaration and its type is "int"
Arrays are obvious when looked that way:

    int arr[5][5];
    int elem = arr[1][2]; // the "arr[1][2]" expression mirrors the declaration

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

#94
post #40
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#.

Well, it's second after Java in TIOBE, which, while not perfect, it checks multiple data points, so it's better than most attempts at guesstimation: http://www.tiobe.com/tiobe-index/ It's #8 on GitHub in projects per language: http://githut.info/ And #18 on Stack Overflow: http://stackoverflow.com/tags (and I'd say most C projects are not as likely to go to GitHub compared to JS or Javascript ones. And C programmers…

(GitHut's data is from 2014)

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

#95

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 don't know if "declarations mirror use" gets you all the way there. You can use: *some_index[arr] (though obviously not saying you should ), but you can't declare: char *5[arr]; Obviously there's good reasons for that, but then you have "declarations mirror use, except when there's good reason not to", which basically brings you back to the original question.

> char *5[arr]

Isn't that exploiting a quirk of the operator's definition, rather than how the operator is intended to be used?

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

#96

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.

I know they're called static array indices, and they're called that because of the use of the keyword `static`, but they don't have to be compile time constant at all (and checks aren't performed at compile time, IIRC). You can have the following:

    void foo(size_t len, int arr[static len]);
Which is really useful in asserting that you won't pass in the null pointer at runtime (so you can remove any `if (arr) {}` checks). Taken further, this exact method is what makes the restrict keyword usable in practice. One of the main problems of the restrict keyword is that you shouldn't be aliasing pointers. By ensuring that your passed-in array isn't actually a null pointer using the above syntax, you avoid one of the biggest problems of aliasing: passing in two null pointers. Consider:

    void foo1(size_t len1, restrict int* arr1, size_t len2, restrict int* arr2);
vs

    void foo2(size_t len1, restrict int arr1[static len1], size_t len2, restrict int arr2[static len2]);
The second is more verbose, but you have a stronger guarantee that this procedure won't be called with pointers aliased to NULL. The compiler can (and I believe in the case of GCC, will) take advantage of this.

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

#97
post #32

Earlier quoted context omitted.

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.

For the rest of the world, its the well-known workhorse of the software world. But it's a workhorse that's continually being replaced. I'm not talking about Rust&Go. I'm talking about C++/Java/C#. Thinking about C projects I saw 15-20 years ago, hardly any of them would be written in C if they where started today. And even in the embedded world C++ is becoming more and more of a thing. Is C used, of course. Is C goin…

The number of devices with embedded software is growing all the time.

These devices are 99% of the time using C. ...therefore the number of C projects is growing, not shrinking.

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

#98
post #77

The thing to keep in mind is Never (Never) use array syntax in your function arguments. It implies something that you can't rely on. More on this: https://lkml.org/lkml/2015/9/3/428

See https://news.ycombinator.com/item?id=13237674 and my corresponding reply, where you _should_ use array syntax for function arguments, but you need to do it using the `static` index syntax.

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

#100

Earlier quoted context omitted.

I've heard this phrase - "declarations mirror use" many times before but it just doesn't click for me for some reason. Who's use? The compiler's or the programmer's? Can you elaborate? Sorry if this silly question but I've scratched my head enough on hearing that phrase that I thought I would ask. Cheers.

The meaning of "declarations mirror use" is that the programmer can use the declared variable in the exact same way as being declared (by applying the exact same operators): int **p; // declares "p" as a pointer to a pointer to int int x = **p; // the "**p" expression mirrors the declaration and its type is "int" This is true even for functions: int *f(int a); // declares a function which takes an int and returns a p…

Thanks for the clear explanation. This makes sense. I do have a tangential question.

I have read that the reason for this declaration syntax is that it was easier form compilers and compiler writers to parse.

How does this declaration syntax facilitate parsing exactly? I fail to see why this is.

Post reply on HN