News for hackers. Stuff that matters.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by dekhn on Tuesday October 17, 2023 @03:44PM (#37920565)
When I see that code my head immediately translates to "store a byte with value 0 at memory address zero". 0 the integer needs to be cast to a char * to treat it as a byte address (rather than a word) and the * means "assign to the memory location given by the pointer.

I would probably use something like this when hacking on an Apple II with a zero page.

I have also written programs that ran on VMS which dumped memory starting at '0' without getting any segfaults.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by zh3 on Tuesday October 17, 2023 @03:54PM (#37920676)
Exactly so [0]. However, these days something or someone somewhere might object "to keep us safe from ourselves"

Turbo-C used to check the zero location to see if it had changed and would issue a warning if so (in the real mode days).

[0] My other computer is a PDP-11,

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by vore on Tuesday October 17, 2023 @04:23PM (#37921044)
You say that as if that's a bad thing – I absolutely need to kept safe from myself, because I need all the help I need to make sure I'm doing things right!
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by sargstuff on Tuesday October 17, 2023 @05:09PM (#37921592)
use a malloc that has the extra saftey features, run under an interpreted C, and several other ways to handle it (sandbox program, emulator, etc). Changing the underlying C language should NOT be one of them.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by AlotOfReading on Tuesday October 17, 2023 @08:27PM (#37923410)
The only way to make C "safe" without modifying the language is to run it in a VM, and even that doesn't fully encompass what people mean by safety.

It's an old language. Some of the fundamental mistakes were just things that were common at the time and only look so bad in hindsight (e.g. strings, locales, nullable pointers, half the k&r standard library). That doesn't mean we can't and shouldn't do better where we can though.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by pjmlp on Wednesday October 18, 2023 @02:59AM (#37925595)
Example, C++/CLI, if certain code patterns are used the code is no longer considered safe from MSIL verifier point of view.

C and C++ targeting WASM, despite all the security message of how great it is, memory locations inside of the same linear memory segment can still be corrupted, thus providing a way to influence the overall execution logic inside of the sandbox.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by sargstuff on Wednesday October 18, 2023 @04:09PM (#37934124)
Oh, so time of 4k memory, have a 4k program and want to strictly reserve/add 3.14159 K to 4k program for automated saftey issues?

At time C was written, swapping in/out of memory measured in literal minutes & when fraction of second of execution time, including swapping in/out of memory, was more than several times the average yearly salary of the day (excluding sneaker net intervention)

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by zh3 on Tuesday October 17, 2023 @05:29PM (#37921858)
I'd agree with that, to the extent that understanding how badly your tools can hurt you is an important thing to learn.

Consider how a surgeon would respond if told not to use a scalpel because of the risk of accidental injury when using a sharp tool.

We learn from our mistakes - to which I'd add, sometimes we can afford to make mistakes (home programs) and other times we can't (safety-critical code).

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by ilyt on Tuesday October 17, 2023 @07:11PM (#37922791)
Surgeon would absolutely use a tool that tells them when they're about to make something that's 99% of the time a mistake.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by ecshafer on Tuesday October 17, 2023 @07:18PM (#37922856)
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 static analysis, unit tests, strong type systems, etc. The evidence seems to favor systems which prevent errors over artisinal expertise.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by Kamq on Tuesday October 17, 2023 @07:42PM (#37923024)
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.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by SilasX on Tuesday October 17, 2023 @11:51PM (#37924678)
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... by dekhn on Wednesday October 18, 2023 @03:56PM (#37933940)
The one thing I remember from watching my wife's surgery is that they counted the surgical sponges going in, and counted them coming back out. Because sometimes surgeons would forget and leave a sponge inside and then the person woudl get a really bad infection.

Honestly, checklists and procedure matter more than most people want to admit.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by sargstuff on Wednesday October 18, 2023 @04:05PM (#37934067)
Was LD_LOAD and related LC stuff (algebra & unix) the 19th c rabbit hole for [1] & [2] ?

1] introducing security vulnerabilities

[2] code changeset submission

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by steveklabnik on Tuesday October 17, 2023 @08:23PM (#37923380)
https://www.sawstop.com

This is my favorite one

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by pjmlp on Wednesday October 18, 2023 @02:56AM (#37925569)
That surgeon has undergone several years training, had to go through an exam to be allowed to practice, and is submited to yearly evaluations if they are still allowed to touch that scapel.

I would agree the same for developers, if similar practices would be enforced everywhere instead of having people calling themselves enginners just because they like how the word sounds.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by kortilla on Wednesday October 18, 2023 @03:47AM (#37925920)
Yet surgeons killed people all of the time and had to be forced to use checklists because it turns out credentialism doesn’t prevent mistakes.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by pjmlp on Wednesday October 18, 2023 @05:00AM (#37926337)
Which is also something that we need to add as well, on top of credentialism.

More quality and process validation, less cowboy programming.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by kortilla on Wednesday October 18, 2023 @08:39AM (#37927760)
And skip the credentialism, because that’s generally bullshit.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by pjmlp on Wednesday October 18, 2023 @08:55AM (#37927911)
Not at all, that is a guarantee that people actually know how to hold the scapel and can enter the operating room safely.

A brick layer doesn't turn into a Construction Engineer, only because they think they know everything about building houses, and have somehow built their own during long weekends.

Likewise a coder out of a bootcamp, isn't someone versed in what actually entails to be a Software Engineer, regarless how cool the title might sound like.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by kortilla on Wednesday October 18, 2023 @09:02AM (#37928032)
No, it’s not a guarantee, it’s just a noisy filter with a very high false negative rate and a high enough false positive rate (as visible in malpractice insurance).
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by pjmlp on Wednesday October 18, 2023 @03:33PM (#37933624)
I certainly is, those numbers would be much higher without that filter.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by kortilla on Thursday October 19, 2023 @10:25AM (#37943347)
I don’t think you know what “guarantee” means. If it was a guarantee, malpractice insurance wouldn’t exist.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by stefan_ on Tuesday October 17, 2023 @03:52PM (#37920635)
On ATmega processors, the register file is mapped to 0, so this would be writing 0 to r0.. which GCC reserves as a dedicated 0 register anyway.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by tzs on Tuesday October 17, 2023 @07:45PM (#37923055)
The PDP-10 did that. There was actually core memory at addresses 0-15 but if you had registers they overlaid that.

Yes, I said if you had registers--if you were cheap you could buy your PDP-10 without registers and all the instructions that referenced registers would use core instead.

Since the registers were in effect just 16 words of fast semiconductor memory overlaying the first 16 words of slow core memory you could do anything in them that you could do in regular memory, including running code out of them.

If you had a small loop that did a lot of iterations you could sometimes get a significant speed boost by copying the loop into the registers and running it there.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by D-Coder on Tuesday October 17, 2023 @08:46PM (#37923551)
I seem to recall stories that if you put a small loop there, it could end up uninterruptible, with the CPU hung.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by sargstuff on Tuesday October 17, 2023 @05:05PM (#37921562)
yes, compiler will align integers on word boundaries. casting to char, just uses the first 8 bits of integer word. Char was originaly just sematic macro for integer. pointer to char is 8 sequenial bits somewhere in the group of integer spaced bits. if you're lucky, the 8 bits are at the start of the integer group of bits, otherwise, segfault.

Originaly using anonymous unions & placing largest bit count variable as first item in union was the context needed to align the "char" correctly -- vs. casting.

Technically, can point at anything in an unaligned manner, just need to align access to machines address boundary to use a "fetch the value of a complete valid memory alignment address". One can hand roll the appropriate shifts/masking to get at the set of bits loaded (which usually let compiler do). Awk and settable end of line marker good way to safely visualize this.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by AlotOfReading on Tuesday October 17, 2023 @08:37PM (#37923482)
I see you've been lucky enough to only work on systems where CHAR_BIT=8. It's not an alignment issue because there may not be a distinct pointer representation for the other bits, rather than alignment issues where a pointer representation exists even if you can't use it.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by defrost on Tuesday October 17, 2023 @10:03PM (#37924065)
Adding to the above, in the 1980s and 1990s it was not uncommon to interface and write code for chips that were 12 bit and 24 bit based (instrumentation accumulators for example, "cheapest sufficient" chips for particular jobs, etc).

Today you can still work with (say) TI DSP chips that spit complex FFT pipelines results once per cycle and have absolutely no 8-bit hardware addressing or masking abilities as they're lean mean RISC optimised machines for pure 32 or 64 bit floating point operations.

They have C compilers and CHAR_BIT==32 (or 64).

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by mananaysiempre on Wednesday October 18, 2023 @05:39AM (#37926564)
Out of curiosity, how do you deal with I/O on such systems? ISO C simultaneously requires that blocks of memory roundtrip through binary I/O (so it can’t truncate chars to octets) and that fgetc() and friends return unsigned chars cast to an ints or EOF (so you really want the range of int to include the range of unsigned char, even if you could technically depend on the implementation-defined overflow behaviour). Then again, I guess “you don’t” could be a valid answer on a DSP.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by defrost on Wednesday October 18, 2023 @07:40AM (#37927298)
It depends entirely on the system as a whole, and it might help to start by forgetting about "ISO C" and start thinking about C the triangle.

* C preprocessor - it's a text substition operation that can be non standard

* C "the language" - just the syntax folks, no library functions here.

* C "the standard library" - for many of us the K&R stdlib was just a proof of concept example of how to code a library, feel free to ditch it and write up your own string handling, for example.

Which brings us to, say, a multi channel marine seismic processing system that has an IBM PC type design with a custom motherboard that has six TI DSP boards slotted in and you're writing code for the user interface to a real time signal aquisition and processing system and writing onboard code for the numerical processing on the DSP boards.

Now, each board handles a streamer cable, each cable has a number of microphones, an external boomer in the water is triggered and the reflective soundwaves from the ocean floor, and the soundwaves that penetrate the seafloor and later also partially reflected by density change layers, are all captured by the microphones.

You have keyboard+mouse I/O between the real time window manager user interface, shared memory I/O between the PC memory and memory on the DSP cards, analogue soundwaves going to sample ports on the DSP cards, block memory I/O going from the PC to a SEG-9 tape recorder, prepared lines of memory going to a plotter to build an image ...

There's a lot going on.

But, as far as the code compiled for the DSP boards, that mostly handles I/O by linking reaction code to interrupt triggers - when the sampling hardware interrupts to signal another bit of soundwave from microphone[i] is ready, that's stashed in a FiFo queue to be pushed into the DSP handling pipe and to be saved in a raw sample buffer.

When a raw sample buffer is full an interrupt is triggered to take the entire buffer via DMA transfer to by handled PC side by sending it to the SEG-9 tape "of (raw) record", when a processed sample buffer is full an interrupt is triggered for a different type of DMA trandfer that takes processed data to display, printer, another SEG-9 track for processed data.

Not much of this is the standard C library, so you can see why you might write your own low level handling.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by sargstuff on Wednesday October 18, 2023 @10:01PM (#37937368)
Stick to delimited ascii & send over tcp/ip, perhaps use asn/bers specs. -- UTF / json / xml nice unification of everything, as long as don't forget sending UTF flag.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by sargstuff on Wednesday October 18, 2023 @09:58PM (#37937350)
ummm... sounds like a unsigned char same as signed char reference. Lot of fun debugging 32 bit int (big, little and mixed endian) over char absolution position always starts at left and is contiguous.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by Kranar on Wednesday October 18, 2023 @02:19AM (#37925378)
You're mostly correct but to be pedantic, in C the literal value 0 does not actually mean address 0. The literal value of 0 is an implementation defined value that represents a null pointer, but that value does not have to be address 0, it could be some other address.

This is significant because the following two snippets of code are not required to be equal in C.

char* c = (char*)(0);

char* d;

memset(&d, 0, sizeof(d));

c == d; // this does not have to be true

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by flohofwoe on Wednesday October 18, 2023 @02:36AM (#37925457)
> that value does not have to be address 0, it could be some other address.

That's what the spec says, but are there any computers around anymore where nullptr is not zero? The spec should really go with the times IMHO, old hardware can be supported via platform-specific language extensions.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by josefx on Wednesday October 18, 2023 @02:54AM (#37925560)
The cleanest way would probably be to get rid of 0 as a null pointer constant, make its use in contexts that expect a pointer illegal and replace it with an explicit keyword. Of course that would break all existing code that uses 0 or (void*)0 instead of NULL, but if you are out to break things anyway you might as well get rid of 40 year old warts.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by gofixurcode on Wednesday October 18, 2023 @03:28PM (#37933562)
Ah a new standard! Perfect! Everyone will adopt this as clearly it is better and there’s no reason not to right? … right?
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by josefx on Wednesday October 18, 2023 @04:05PM (#37934061)
Well it should be backwards compatible if you just use NULL everywhere where it is appropriate, so you wouldn't even have to sprinkle ifdefs all over the place. Code that uses 0 all over the place would probably have to be updated with the help of compiler errors and a static code analyzer.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by Kranar on Wednesday October 18, 2023 @03:00AM (#37925606)
>That's what the spec says, but are there any computers around anymore where nullptr is not zero?

Yeah that's absolutely fair. I actually can't think of a single platform, embedded or otherwise, old or new, where the null pointer is not address 0.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by camel-cdr on Wednesday October 18, 2023 @03:10AM (#37925665)
I've seen a compiler that has an alternative null pointer address, but I couldn't find it again.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by msla on Wednesday October 18, 2023 @10:57AM (#37929619)
https://c-faq.com/null/machexamp.html

> Depending on the ``memory model'' in use, 8086-family processors (PC compatibles) may use 16-bit data pointers and 32-bit function pointers, or vice versa.

And it isn't just zero anyway because there's segmentation in play.

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by billyoneal on Sunday October 22, 2023 @01:17AM (#37973013)
The big place where it happens in modern environments are for pointers to members, where 0 is a bad nullptr value because the member at index 0 is legitimately a thing you want to name. MSVC uses -1 for nullptr in such cases.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by sargstuff on Wednesday October 18, 2023 @04:00PM (#37934002)
Perhaps a hascii take on the bending spoon in the matrix scene would be better *char reference.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by dekhn on Wednesday October 18, 2023 @06:14PM (#37935498)
How do you reference literal address 0, then? From how you describe it sounds different from literal address 1, etc.
Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by sargstuff on Wednesday October 18, 2023 @09:46PM (#37937240)
somewhat covered in different hacker news post, for C, roughly:

   []

   *()++
Technically, can only do address "1" with first bit set as a valid, usable address on hardware allowing addressing smaller than 8 bits (standard hardware epsilon factor).

So really, address one is literally address 0 + epsilon, where epsilon is minimal addressable bit group, typically 8 bit clean without seg fault.

Although, for standard x86, epsilon size would depend on which ring/boot method level & asm addressing method available (8,16,32,64).

Re:*(char*)0 = 0; - What Does the C++ Programmer Intend with... by flohofwoe on Wednesday October 18, 2023 @02:39AM (#37925474)
> I have also written programs that ran on VMS which dumped memory starting at '0' without getting any segfaults.

That's also totally valid on WebAssembly btw, address 0 is a regular read/write location.