Re: C- Syntax to allocate Global variables to consecutive memory locations



Hans-Bernhard Bröker wrote:
David Brown wrote:
Hans-Bernhard Bröker wrote:

[...]
For those who insist on examples instead of standard-ese: there's nothing to stop a platform from simply not having any addressable memory address (void *)0x8000. And there sure as manure is no requirement for this memory, if it exists, to be _writable_.

The above code is about as far from being "correct standard C" as any piece of code can be, while still passing through a typical C compiler.

I think the code is "correct", under certain reasonable assumptions -

That's a delusion. The code is incorrect, precisely *because* you have to make external assumptions to avoid it causing undefined behaviour.


*Any* program exists in the context of its run-time environment, and programs make all sorts of assumptions about that environment. These assumptions are not in the code, because there is no way to write them in the code. Even if were possible, in this case, to tell the compiler at the memory at 0x8000 works as you want, then there would still be other assumptions.

At what point do you start to accept these external assumptions? Do you accept that the memory interfaces on the card work (there may be hardware errors, or occasional ram bit errors)? Do you accept that the processor works (they've been known to have bugs)? Do you accept that integer arithmetic "works" at a mathematical level (you can't prove it)?

Back here in the real world, it's fair to assume that the memory at 0x8000 works as expected. It's possible that the code will contain comments to that effect, but it might be implied by the platform in use. It should of course be clear what is going on - that's part of writing good code.

that the memory exists, is addressable, is writeable in this way, and that the compiler will make the same assumptions.

None of those assumptions are part of the code sample in question.

By the same logic, I would say the following is "correct" C:

extern void bar(char* p);
void foo(void) {
char buffer[1000];
bar(&buffer[999]);
}

There is absolutely nothing in the C standards that guarantees that the platform can allocate 1000 bytes on the stack (or simulated stack)

Actually, to some extent there is: C99 5.2.4.1: the 65535-byte object requirement.

Are you happy then that "foo" is correct code, while foo2 below is not? And incidentally, does a C99 compliant compiler suddenly become non-compliant if the linker script does not provide 64k of stack space?

void foo2(void) {
char buffer[10000];
bar(&buffer[999]);
}


mvh.,

David
.