Live data from Hacker News

A convenient untruth: Array notation in C is a lie

blog.feabhas.com

101–110 of 176 posts

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

#101
post #21

The equivalent in C# always made more sense to me (not comparing memory or allocation model between the languages, but simply syntax in relation to a person reading it): int[] arr = new int[5]; // C# int arr[5]; // C The fact that the brackets go on the datatype always made more sense to me, after all, I want to refer to memory of a certain cell size (as indicated by int). I realize that there is a lot of stuff going…

Unfortunately this is differently wrong in C# (and many other modern languages). arr here is not an array at all, but is actually a reference to an array and has different semantics from the the corresponding C declaration.

This is not just being pedantic: using the same syntax for values and references does lead to confusion. At least C# has actual value types and 'ref' (but not value type arrays AFAIK), in Java this is still being worked on.

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

#102
post #68

Earlier quoted context omitted.

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();

Jesus and you guys say JavaScript is bad...

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

#103

Earlier quoted context omitted.

> 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. arr and arr2 are indeed distinct types. They are of type int[5] and int[7]. You can see this by checking that they have different sizes, or that `printf("%s\n", std::is_same ::value ? "true" : "false");` will…

Sizes aren't types though, and if I'm not mistaken that line of code is c++ no?

Yes, it is c++, but both the concept of array and type decay comes from C.

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

#104
post #21

The equivalent in C# always made more sense to me (not comparing memory or allocation model between the languages, but simply syntax in relation to a person reading it): int[] arr = new int[5]; // C# int arr[5]; // C The fact that the brackets go on the datatype always made more sense to me, after all, I want to refer to memory of a certain cell size (as indicated by int). I realize that there is a lot of stuff going…

It was always puzzling to me why people stick to

  char *foo 
instead of

  char* foo
foo is obviously a pointer to the char, not a char. It has different size and behavior.

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

#106

Earlier quoted context omitted.

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.

The advantage is that you don't introduce any new operators or syntactic forms which would only be used in declarations. This means a smaller set of tokens and a smaller set of syntactic forms. Being able to parse an expression like

    (*arr[i])(42)
means that you can use pretty much the same machinery to parse

    int (*arr[SIZE])(int a)

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

#107
post #21

The equivalent in C# always made more sense to me (not comparing memory or allocation model between the languages, but simply syntax in relation to a person reading it): int[] arr = new int[5]; // C# int arr[5]; // C The fact that the brackets go on the datatype always made more sense to me, after all, I want to refer to memory of a certain cell size (as indicated by int). I realize that there is a lot of stuff going…

It was always puzzling to me why people stick to char *foo instead of char* foo foo is obviously a pointer to the char, not a char. It has different size and behavior.

That's because [1]

  char* foo, bar;
doesn't mean what one would expect it to mean.

[1] as per Rule of Maximum Astonishment.

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

#108
post #3

I don't know how this is a lie or untruth, even in jest. In a language that exposes memory management directly of course you can manually traverse an array.

It's just a different way of looking at C that might resonate with someone new to the language and the idea of exposed memory. There's no "lying" but by framing it like a story or an evil conspiracy it might make it interesting or fun enough to stick when a clinical description might not for many students.

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

#109
post #21

The equivalent in C# always made more sense to me (not comparing memory or allocation model between the languages, but simply syntax in relation to a person reading it): int[] arr = new int[5]; // C# int arr[5]; // C The fact that the brackets go on the datatype always made more sense to me, after all, I want to refer to memory of a certain cell size (as indicated by int). I realize that there is a lot of stuff going…

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…

>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

For what is worth, they are really different types in C++ (they can still decay to pointers for compatibility with C).

edit: netheril96 pointed out exactly the same thing.

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

#110

Earlier quoted context omitted.

It was always puzzling to me why people stick to char *foo instead of char* foo foo is obviously a pointer to the char, not a char. It has different size and behavior.

That's because [1] char* foo, bar; doesn't mean what one would expect it to mean. [1] as per Rule of Maximum Astonishment.

I find that

char* foo = NULL;

char bar = 0;

are preferable. Is there any reason one would want to smash N declarations into one?

Post reply on HN