Live data from Hacker News

*(char*)0 = 0; – What does the C++ programmer intend with this code? [video]

youtube.com

101–110 of 199 posts

Re: *(char*)0 = 0; – What does the C++ programmer intend with this code? [video]

#101

Not a big fan of the format of the talk. The guy is a good orator, but it takes ages to go to the point. A bit annoying if you're actually interested in the technical part rather than the jokes.

Yup, I’m not going to burn 54 minutes of my life listening to something that should take 30 seconds to convey.

Re: *(char*)0 = 0; – What does the C++ programmer intend with this code? [video]

#102
post #23

This statement would be technically legal on its own in x86 real mode if the compiler didn't do null pointer checks. However it would set the divide-by-zero IRQ handler to itself 0000:0000, and when the next division by zero happened, the machine run into UB (likely a reset or halt) because it would jump there, do 4x ADD byte ptr [BX + SI], AL (or ADD byte ptr [EAX], AL) followed by running the remaining interrupt ve…

If I'm understanding what you're saying correctly, the memory location with address 0 is actually a writable address, but with the value being used semantically to handle division by zero? It's kind of wild to me that would even something that's even allowed to be done manually, let alone required by a certain mode. Is this something provided for compatibility reasons that you'd have to opt into, or is it just someth…

Which part is wild? "Magic" memory addresses are a fairly normal way to communicate with hardware; nowadays there are more layers to how you set up mappings in the MMU etc., but in the old days it was normal for everything to just have a fixed address (e.g. I remember back on the Apple ][ the screen's framebuffer was in a particular memory range, or rather two - to avoid tearing you'd draw on one and then flip which one it was using). And particularly for the CPU, it's hard to see how else it could do customizable interrupt handling - I guess you could have some kind of special API with dedicated CPU instructions or something for "programming" in an interrupt table, but that would be more complex and have no particular benefit. "It reads your table of pointers from this address in memory, in this format" is pretty straightforward and easy to use.

As for why it's address 0, well, it has to go somewhere, every machine has a CPU so everyone needs an interrupt table even if they don't have much memory. And when memory was precious there was no sense wasting even one byte of it; 0 was a real address on your physical memory chip, so why not use it just like any other?

(The fact that it's "address 0" for "division by 0" is just coincidence as far as I can see; division by 0 just happens to be the first kind of possible CPU interrupt. Perhaps it was the most common one?)

Re: *(char*)0 = 0; – What does the C++ programmer intend with this code? [video]

#103
post #63

Earlier quoted context omitted.

I think a more accurate analogy would be some kind of scalpel that would not let the surgeon cut deeper than they needed. So if they needed a 1 cm incision, it would somehow stop the blade form going in 1.1 cm. In that case, some experienced surgeon may say "But I know how to make a 1cm incision!", but I think that the reality is that preventing a mistake from happening is valuable. You see the same arguments against…

I think an even more accurate analogy would be if a surgeon had some kind of scalpel with a 1 cm limit, but if a surgery suddenly changes in the middle, and suddenly requires a deeper incision, the surgeon has to spend a non-zero amount of time re-configuring the scalpel. This casts flexibility vs safety as a tradeoff, which it is.

Oh, one more refinement:

Surgeons are constantly killing people[1], and every time, it turns out it was because the surgeon disabled a known, recommended safety rail, and whenever anyone points out that they should stop disabling the safety rails, they insist that they know how to operate without them, it's those other people that don't. Plus it's sooooo inconvenient for an operation[2] to take five more minutes, they're too good to have to deal with that.

[1] introducing security vulnerabilities

[2] code changeset submission

Re: *(char*)0 = 0; – What does the C++ programmer intend with this code? [video]

#106
To me this talk was rather confusing. This statement cannot occur in a well formed standard C or C++ program, and I don’t think that the speaker did a good job conveying this. They also took way too much time to get to the actual point. If the intention was to discuss the particularities of memory mapping on some popular systems, they should have used bitcast from the start.

Re: *(char*)0 = 0; – What does the C++ programmer intend with this code? [video]

#107
Kind of a tangent, but I've never seen that signature for main with char *apple at the end after char *envp.

What's passed in there? Some googling let me know it's used on macOS, but every result was too generic to be helpful.

Re: *(char*)0 = 0; – What does the C++ programmer intend with this code? [video]

#108
post #91
post #76

Earlier quoted context omitted.

> sizeof char is 1 by definition everywhere. Parentheses are required around char because it's a type. /pedantic

That is incorrect :-). sizeof is an operator in C, and does not need parenthesis any more than pointer operator *. It is true that programmers frequently think of it as a function and use parenthesis.

It's not that simple!

To begin with, sizeof has two syntaxes: the first, which is the one you seem to refer to, is simply

  sizeof expression
where expression involves variables and constants, not types. The second is

  sizeof (type)
where the parentheses are mandatory.

Then, even in the first syntax, even if sizeof is listed among the operators, even if it doesn't look any different from "pointer operator ", nonetheless it has strange priority rules. For example

  sizeof (T) *x
If it was a regular prefix operator obeying priority and right-to-left evaluation, this would mean: dereference x, cast it to T, and return its size. Instead the C standard forces the compiler to interpret it as: take the size of type T and multiply it by x.

Re: *(char*)0 = 0; – What does the C++ programmer intend with this code? [video]

#109

Not a big fan of the format of the talk. The guy is a good orator, but it takes ages to go to the point. A bit annoying if you're actually interested in the technical part rather than the jokes.

If you use GPT-4 with Browsing turned on and supply it with the title, it will find the page and use the transcript and you can ask it questions. Then you can look at the transcripts to find the spots and verify. Alternatively, if you have an AI-enabled browser you can ask it about the transcript once you open it.

> If you use GPT-4 with Browsing turned on

do you mean the browsing plugin, or using base GPT-4?

Re: *(char*)0 = 0; – What does the C++ programmer intend with this code? [video]

#110
post #84

Earlier quoted context omitted.

Char can be the same size as short or int. You can't assume it is one byte.

You can't assume char is one octet . It is one byte by definition. A byte is CHAR_BIT bits, where CHAR_BIT >= 8. (It's exactly 8 on most implementations; DSPs are the most common exception). short and int are both required to be at least 16 bits wide. It's possible for int to be 1 byte (sizeof (int) == 1), but only if CHAR_BIT >= 16.

A clarification: You can certainly assume that char is 8 bits if you don't mind losing portability to a small minority of systems.

If I'm being pedantic, I might add something like

    #if CHAR_BIT != 8
    #error "This code assumes 8-bit char"
    #endif
But realistically, if I'm using headers defined by either POSIX or Windows, that's probably enough of a guarantee. (Though I'd still use CHAR_BIT rather than 8 to refer to the number of bits in a byte.)
Post reply on HN