Live data from Hacker News

Pointers in C (2010)

boredzo.org

51–60 of 113 posts

Re: Pointers in C (2010)

#51

Earlier quoted context omitted.

> `uint8_t` and `char` are not guarenteed to be the same type Remember that `char`, `signed char` and `unsigned char` are the different types, even though `char` takes the same range of values as either `signed char` or `unsigned char`. The typedef `uint8_t` is usually set to `unsigned char`, not `char`, even on systems where `char` is unsigned. Partly this reflects the fact that `char` is usually used to represent a…

> I believe all current major implementations typedef `uint8_t` to `unsigned char` That can't be right, because CHAR_BIT is not always 8.

It depends on what you count as a "major implementation".

Re: Pointers in C (2010)

#52
When graphical gimmics steal the show: https://boredzo.org/pointers/boxes.png visualizes both pointers and their target (an integer) as 3d boxes. So the sizeof(int) is the edge length of this target?

Normally we see such guiding images with 2d boxes. There's nothing wrong with 3d because clearly, integers are also not 2d (they are not even 1d). However, don't associate the size of theses boxes with the memory size of an element. This overstresses the analogy and suggests the whole thing is a vector space, but it isn't.

Re: Pointers in C (2010)

#53

Earlier quoted context omitted.

The spiral rule is wrong. It breaks for things as simple as arrays of arrays. // +---------+ // | +--+ | // | ^ | | int /*|*/ aa[2][3]; // ^ | | | // | +------+ | // +--------------+ The correct result is "aa is a (2-element) array of a (3-element) array of ints". To get the correct interpretation, you have to know that the spiral has to avoid the "int" element after passing through "[2]". This defeats the purpose of…

A good exercise is to then guess why the spiral rule seems to work most of the time even though it is inherently wrong. The reason is that some types that are syntactically valid are forbidden by C/C++. You cannot have a function returning a function. A function returning an array. An array of functions. You can only have a pointer to these (function returning a pointer to function/array or an array of pointer to fun…

Aha, so the final working algorithm is "the spiral rule but with a rightward detour on arrays of arrays."

Re: Pointers in C (2010)

#54
post #39

Earlier quoted context omitted.

"char" is portable and by definition sizeof(char) == 1 and on top of that char pointers can alias other types. If I could time travel and influence the design of C the first things I'd do is change switch to break by default. The 2nd thing I'd do is rename "char" into "byte" since that's effectively what it is (and it's seldom a character these days since we often use UTF-8 or other multi-byte encodings).

> The 2nd thing I'd do is rename "char" into "byte" since that's effectively what it is This isn't always true. See machines where CHAR_BIT > 8.

I always thought that 1 char was exactly 1 byte, but that 1 byte was not necessarily 8 bits?

Re: Pointers in C (2010)

#55

Earlier quoted context omitted.

> The 2nd thing I'd do is rename "char" into "byte" since that's effectively what it is This isn't always true. See machines where CHAR_BIT > 8.

I always thought that 1 char was exactly 1 byte, but that 1 byte was not necessarily 8 bits?

I think from a C standards point of view, that's true; I was using the general convention of 1 byte=8 bits, but char being one or more of these bytes. Hence CHAR_BIT is the number of bits in a char, and sizeof gives the number of chars that would fit in the specified type.

Re: Pointers in C (2010)

#56
post #2

I always wonder what makes pointers so difficult for some. So far I have always been able to explain it to people by drawing a linear memory space and then showing how different types are allocated. It seems to me that pointers are one the easier concepts in programming.

I believe because it is taught the wrong way and with a confusing notation. We do int ptr instead of int ptr and talk about memory instead of just saying: "It is simply a box containing 1 value, we can also make a box containing a box containing the value." Luckily, I don't do C.

[deleted]

Re: Pointers in C (2010)

#57
post #53

Earlier quoted context omitted.

A good exercise is to then guess why the spiral rule seems to work most of the time even though it is inherently wrong. The reason is that some types that are syntactically valid are forbidden by C/C++. You cannot have a function returning a function. A function returning an array. An array of functions. You can only have a pointer to these (function returning a pointer to function/array or an array of pointer to fun…

Aha, so the final working algorithm is "the spiral rule but with a rightward detour on arrays of arrays."

Forget the spiral rule. That's putting an if-statement into a buggy algorithm instead of using the correct algorithm.

The simplest correct algorithm is to 1. From the identifier, go right one by one in the current parenthesis level and process every element. 2. From the identifier again, go left one by one in the current parenthesis level and process every element. 3. Repeat from step 1. except the "identifier" is the part you already processed.

Within step 1, you will encounter arrays and function parameter lists. Within step 2, you will encounter pointers (in C++ also references), const and volatile modifiers, and named types. Neither algorithm covers it, but if there is no identifier to start with, then you start at the most nested level between the elements that may occur in step 1 and 2 and if you find a comma, you were just processing the type of a function parameter.

Spiraling is unnecessary. Within step 1, you DON'T spiral because of arrays of arrays or you turn back because of a closing parenthesis so a spiral doesn't need to guide you. Within step 2, the elements on the right are all processed already, so a spiral going back right will hit nothing. For simple but common cases like "const int * ptr * const_ptr_to_const_int" you're spiraling around nothing on the right-hand side.

Let's rework and simplify the examples from the http://c-faq.com/decl/spiral.anderson.html page. Comments show what the result of parsing an element is. Process >> >> left to right and

         char * str [10];
    //          XXX >>>> "str is", "an array of 10..."
    //   >>>>>>>>>>>>>>> "a function taking (int, float*) and returning"
    //   >>>>         "a function taking (int) and returning"
    //                        >>>>>>>>>>>>>>>>>>>>>>>        "signal is", "a function taking (int, void(*fp)(int)) and returning"
    //         >>>> "a function taking (int) and returning"
    //   
Notice that in the examples where Anderson drew any spirals, it only made sense because there was a single ">" element to the left and to the right of the XXXX part. In all other cases, spirals don't make sense because you might have to avoid the element on the left or there is no element on the right to spiral through, you're just going right-to-left. Why fit a spiral when a straight-line arrow will do?

Re: Pointers in C (2010)

#59
post #4

I checked the section "Interlude: Arrays" because the relationship between pointers and arrays in C is a major sticking point. It claims that, given a declaration int array[] = { 45, 67, 89 }; the expressions "array", "&array", and "&array[0]" are all equivalent. They are not. "&array" and "&array[0]" both refer to the same memory location, but they're of different types. In the next section: "By the way, though size…

Dude, I've just been asked to teach c pointers and this was super helpful. Got a good c++ FAQ? :)

Re: Pointers in C (2010)

#60
post #11

Ah, boxes again. For me, all confusion about C's pointer-happiness cleared up when I finally realized that C (and Asm, I guess) works with heap memory as a big blob of bytes, and it's programmer's job to keep the blob's contents from getting messed up―with some thinly-veiled help from the language and the compiler. Everything else, including variables, is just syntactic sugar when it points to the heap. (With the cla…

My favorite proof that C arrays and strings are actually just syntactic sugar for pointer arithmetic is that the following are all valid and equivalent: char theLetterC = "ABC"[2]; char theLetterC = *("ABC" + 2); char theLetterC = *(2 + "ABC"); char theLetterC = 2["ABC"]; "You can't prove anything about a program written in C or FORTRAN. It's really just Peek and Poke with some syntactic sugar." -Bill Joy

    char theLetterC = 2["ABC"];
Wait, what? And I thought I was good with pointers...

Edit: I think I got it, is it this?:

"ABC" + 2 == 2["ABC"] == *(2 + "ABC")

Right?

Post reply on HN