5 ms·
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
by dekhn 3y ago
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.
- stefan_ 3y agoOn 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.
- tzs 3y agoThe 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.
- D-Coder 3y agoI seem to recall stories that if you put a small loop there, it could end up uninterruptible, with the CPU hung.
- zh3 3y agoExactly 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,
- vore 3y agoYou 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!
- sargstuff 3y agouse 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.
- AlotOfReading 3y agoThe 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.
- pjmlp 3y agoExample, 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.
- sargstuff 3y agoOh, 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)
- sargstuff 3y agoyes, 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.
- AlotOfReading 3y agoI 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.
- defrost 3y agoAdding 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).
- mananaysiempre 3y agoOut 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.
- Kranar 3y agoYou'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
- flohofwoe 3y ago> 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.
- billyoneal 3y agoThe 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.
- josefx 3y agoThe 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.
- gofixurcode 3y agoAh a new standard! Perfect! Everyone will adopt this as clearly it is better and there’s no reason not to right? … right?
- 3y ago
- flohofwoe 3y ago> 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.