Re: OK folks, corrected



On Sun, 09 Mar 2008 11:25:42 +0100, jacob navia wrote:
Harald van Dijk wrote:
On Sun, 09 Mar 2008 09:34:34 +0100, jacob navia wrote:
Harald van Dijk wrote:
On Sun, 09 Mar 2008 01:14:38 +0100, jacob navia wrote:
In standard C you can say that a pointer is non null with

int function(int tab[static 1]);

tab must point to at least one element, hence it can't be NULL.
True, but this also disallows other valid non-null pointer values
from being passed to that function, such as a pointer to the end of
an array.
No, since this tells the compiler that this pointer can be 1 or more
elements, nothing more.

So when it's really 0 elements, you have a problem.

Yes of course. Every day I pass arrays of zero elements (that can't be
null) to functions. I have only problems.

Consider a simple function to zero out a block of memory. You might give
it a size parameter, but another equally legitimate declaration is

void clearmem(void *start, void *end);

where neither start nor end is allowed to be a null pointer, _but_ end
will usually not point to anything.

Let's try your suggestion.

void clearmem(void start[static 1], void end[static 1]);

This is not valid, since you can't have arrays of incomplete type. (By
itself, this is another argument for a separate indicator that an argument
must not be null.) Okay, let's try giving it unsigned char *, because we
happen to know that in this program, it will only be used with byte arrays
anyway, and it's possible to cast if required.

void clearmem(unsigned char start[static 1], unsigned char end[static 1]);

As you can test any day too

int tab[0];

is illegal C.

Obviously.

And if you pass a pointer to 1 past the end of the array, you can't
access it until you decrement it. Since the compiler will NOT verify the
address anyway, the syntax I proposed will work.

The behaviour will be undefined, and the compiler will be permitted to
make the function access *end. This will be allowed even if the function
does not actually access *end.

Suppose the compiler can tell that for your processor, it would be more
efficient to save *end, then clear from *start to *end (inclusive), and
finally restore *end. You told the compiler that *end exists, so this is a
perfectly legitimate optimisation. Now suppose that the access to *end
aborts your program.

The result is a visible bug in the program. This bug will need to be
fixed. This bug can be fixed by dropping the misuse of '[static 1]' as
meaning 'nonnull'.
.



Relevant Pages

  • Re: OO programming - illumination? - whoopsie
    ... > represented by a host of loosely related arrays. ... > compiler and the memory allocators. ... A pointer is usually a word. ... organs can be further modeled to include cells and so on and so forth. ...
    (comp.lang.java.programmer)
  • Re: OO programming - illumination? - whoopsie
    ... represented by a host of loosely related arrays. ... compiler and the memory allocators. ... As a matter of fact there is no such thing as a pointer. ... memory that just holds a terminator, which is 0 by convention. ...
    (comp.lang.java.programmer)
  • Re: forwards declarations!
    ... h, long m, int w, int l); ... compiler obviously doesn't. ... LRESULT callerFunction(HWND, long, WPARAM, LPARAM), HWND ... Not quite the same as straight forwards function pointer usage. ...
    (microsoft.public.vc.language)
  • Re: Program speed execution question
    ... It might also be cache size, memory speed, total memory, or other features of the two machines, or it could be that the compiler optimizations are different for the two machines. ... With pointer arrays, the compiler must often assume that the arrays can overlap through hidden aliases, and this inhibits many optimizations. ...
    (comp.lang.fortran)
  • Re: Arrays and Functions (how to clean up code)
    ... int main{ ... If you change meqn and mx to #define macros, ... for variable length arrays. ... compiler diagnostic is required. ...
    (comp.lang.c)