top | item 37920331

(no title)

sacnoradhq | 2 years ago

Find me one contemporary example (ANSI C) with a disassembled screenshot.

This is writing sizeof(char) (== 1 almost everywhere) zero to address zero. It is not using a NULL macro or other predefined symbol.

In the real world, this would generally write a byte to address 0000:0000, leading to UB because it would fuck up the divide-by-zero IV.

PS: I used Borland C++ 3.1, Microsoft C++ 3.x and 4.5x, Watcom, and early GNU.

discuss

order

monocasa|2 years ago

> Find me one contemporary example (ANSI C) with a disassembled screenshot.

Here in godbolt, clang compiling C simply deletes the code in the function past and including the null pointer dereference.

https://godbolt.org/z/9aqWPazsP

> This is writing sizeof(char) (== 1 almost everywhere)

1 everywhere. sizeof's unit is "how many chars". For instance there was a cray machine that could only access 64bit words. sizeof(char) is still 1, with 64bit chars.

> zero to address zero. It is not using a NULL macro or other predefined symbol.

NULL is defined as literal 0.

gpderetta|2 years ago

make it a '*(volatile char*)0 = 0' to force the store.

gpderetta|2 years ago

> sizeof(char) (== 1 almost everywhere)

sizeof char is 1 by definition everywhere.

/pedantic

shric|2 years ago

> sizeof char is 1 by definition everywhere.

Parentheses are required around char because it's a type.

/pedantic

lmm|2 years ago

In the mathematical sense of almost, a property that holds everywhere does qualify as holding almost everywhere.

cjensen|2 years ago

Regarding your PS, I used Borland's Turbo C++ 1.0, and I think you've forgotten that memory models existed. Honestly, that's a good nightmare to forget.

HybridCurve|2 years ago

I hated that about DOS, real-mode and BC++. After about 6-8 months of that misery, installing linux and learning to write C code with GCC was the best thing that ever happened to me. I felt like an animal being released from a cage and into the wild.

dbrower|2 years ago

It doesn't have to be the NULL macro, which is correctly defined as plain 0.

The literal 0 is treated specially, so this could indeed be one of those 'turns into a weird bit pattern NULL pointers', if such a thing existed in the wild anymore.

But you're correct in that there probably haven't been any since the turn of the century or whenever the last Univac mainframes got turned off.

pests|2 years ago

Apparently according to the c-faqs link elsethread

    execl takes a variable-length, null-pointer-terminated list of character pointer arguments, and is correctly called like this:
    execl("/bin/sh", "sh", "-c", "date", (char *)0);
Due to ececl being a variadic function it can not take advantage of a prototype to instruct the compiler that one of its arguments needs to be treated as a pointer context.