If realloc(nonnull, 0) returns NULL, has the object been freed?
Or, before this thread explodes: Is there already a definite answer
in a DR or some other thread?
Google found me plenty of threads about "does it return NULL?", and
some which touched the above question too, but I didn't find a clear
answer. Nor did I find a DR about it, but I don't know where to find
a list of all C99 DRs either.
Extracts from C99:
7.20.3 (Memory management functions):
1 If the size of the space requested is zero, the behavior is
implementation-defined: either a null pointer is returned, or
the behavior is as if the size were some nonzero value, except
that the returned pointer shall not be used to access an object.
7.20.3.4 (The realloc function):
2 The realloc function deallocates the old object pointed to by
ptr and returns a pointer to a new object that has the size
specified by size. (...)
The implementation may return NULL when size=0. The above implies
that if it does, realloc(nonnull, 0) frees the object first.
3 If memory for the new object cannot be allocated, the old object
is not deallocated and its value is unchanged.
4 The realloc function returns a pointer to the new object (which
may have the same value as a pointer to the old object), or a
null pointer if the new object could not be allocated.
The implementation may try to return a non-NULL object. The above
implies that if it does, a NULL return comes from a realloc failure
and the object has not been freed.
C89 4.10.3.4 (or at least my draft of it) said realloc(nonnull, 0)
freed the object, but this sentence has been removed from C99.
--
Regards,
Hallvard
>The implementation may return NULL when size=0. The above implies
>that if it does, realloc(nonnull, 0) frees the object first.
...
>The implementation may try to return a non-NULL object. The above
>implies that if it does, a NULL return comes from a realloc failure
>and the object has not been freed.
The question is surely whether, on a system that returns NULL for
malloc(0), a realloc(nonnull, 0) may *fail*, in which case it must
return NULL and not free the memory. This seems allowable but
perverse, since how can the system fail in such a case?
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
The case for malloc(0) is unique and looks like realloc(NULL, 0). In my
view, malloc(0) should return NULL. It makes no sense to return a
pointer to zero bytes of storage. There is no case for
realloc(nonnull,0) to fail. free() does not have a failure mode.
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
No. If realloc(nonnull, 0) attempts to return non-NULL, presumably
malloc(0) attemts the same - though I don't see that the standard
requires that.
--
Regards,
Hallvard
I was considering the case where both malloc() and realloc() return
NULL for zero bytes, but where - somehow - realloc(nonnull, 0) could
fail. In that case, realloc(nonnull, 0) would return NULL both
when it fails and succeeds, but when it fails the memory would not
have been freed.
Obviously it's absurd for realloc() to fail in that case, but I don't
know that the standard prohibits it.
Yes, and that is _not_ what I was asking about. What I'm talking about
is: When realloc(nonnull, 0) has returned NULL, can the caller know
whether or not the object has been freed - when the caller doesn't know
whether or not the implementation always returns NULL from
realloc(nonnull, 0) (and malloc(0))?
--
Regards,
Hallvard
No. But again a good implementation would never fail for a realloc of
zero bytes: even if it would normally try to allocate a small block,
it can always succeed by returning the original nonnull value.
No. realloc returns a null pointer (only) if the new object could
not be allocated, and if memory for the new object cannot be
allocated, the old objct is not deallocated and its value is unchanged.
Thats directly from the realloc spec (C99 7.20.3.4).
Actually when size is specified as zero, there is explicit license
in the C standard for a conforming implementation to either
successfully allocate some amount of storage or to return a
null pointer (indicating allocation failure). The original
question cannot be resolved by taking that approach..
OK, I see it now. Though 7.20.3 says the allocation functions can
return NULL for size=0, the only text which says says realloc may free
the old object is for when it is going to return non-NULL. So this
case is opposite from C89, where realloc(nonnull, 0) freed the object.
Then a general realloc() call can be handled like this:
newobj = realloc(oldobj, size);
if (!newobj) {
#if __STDC_VERSION__ < 199901L
if (size)
#endif
free(oldobj);
return;
}
--
Hallvard
It seems to me that this causes massive problems for people wishing to
write libraries that conform both to C90 and to C99. Are there other
similar cases where the behaviour for a library call is defined in both
C90 and C99, but with different effects?
Well, not all that massive in this case. I should have said "once you
have done realloc without checking the arguments, you can handle it like
this". It does get cumbersome if you want the assignment to be a
separate statement though.
--
Hallvard
Harald van Dijk wrote:
>Hallvard B Furuseth wrote:
>> Then a general realloc() call can be handled like this:
>>
>> newobj = realloc(oldobj, size);
>> if (!newobj) {
>> #if __STDC_VERSION__ < 199901L
>> if (size)
>> #endif
>> free(oldobj);
>> return;
>> }
>
> It seems to me that this causes massive problems for people wishing to
> write libraries that conform both to C90 and to C99. (...)
Well, not all that massive in this case. I should have said "once you
have done realloc without checking the arguments, you can handle it like
this". It does get cumbersome if you want the assignment to be a
separate statement though.
Otherwise:
if (!(size && (newobj = realloc(oldobj, size)))) {
free(oldobj);
return;
}
--
Hallvard
Sorry that I wasn't clear; I copied too much of your post. I agree that
a program can easily be written that works with either C90 or C99's
realloc, but I was asking about a single realloc function that works
with either C90 or C99 programs.
void free(void *ptr) {
realloc(ptr, 0);
}
A NULL return from realloc here is just fine.
> Then a general realloc() call can be handled like this:
>
> newobj = realloc(oldobj, size);
> if (!newobj) {
> #if __STDC_VERSION__ < 199901L
> if (size)
> #endif
> free(oldobj);
> return;
> }
If newobj is not a null pointer, then realloc was successful. If newobj
is a null pointer, and size != 0, then realloc failed. If newobj is a
null pointer and size == 0, then a priori there are two possibilities:
The allocation of 0 bytes was supposed to produce a non-null pointer
and failed (oldobj is intact), or it successfully returned a null
pointer (oldobj has been free()d).
In C99, it is implementation defined whether the size == 0 case behaves
as in C90 or tries to return a non-null pointer. To make the right
decision _after_ the realloc call, you have to use your knowledge of
the implementation.
You could write
if (size == 0) { free (oldobj); newobj = malloc (0); }
else { newobj = realloc (oldobj, size); if (newobj == NULL)
handle_failure (); }
It's related to the 0-length data issue; although WG14
decided not to require support for 0-length arrays etc.,
it is undoubtedly more convenient for a programmer to have
p = malloc(n*sizeof(t));
rather than
p = n? malloc(n*sizeof(t)): NULL;
Presumably p would be used safely, since whatever loop
through array elements is coded would prevent dereferencing
p. p should have a different value than any other active
allocation, since that property is often used in programs.
Rather than require implementations to go one way or the
other on this, WG14 left it up to implementors to decide
what their users would prefer. Frankly, I think we should
have allowed 0-sized objects throughout the standard, for
reasons that we could discuss elsewhere.
Sure it can; that is explicitly allowed by the C99 standard.
> This particular call gets wrapped inside ..
> void free(void *ptr) {
> realloc(ptr, 0);
> }
> A NULL return from realloc here is just fine.
I must say I didn't understand that example. A conforming
implementation of the standard free function must *not* do
that, because either it fails to allocate and thus does not
free up the previous storage, or it successfully allocates,
frees the old storage, and the new block is lost track of,
causing a memory leak.
No, you still can't detect memory exhaustion. A system that has to
allocate a minimum space to keep track of things may not be able
to, due to complete exhaustion. It may be too stupid to just
reduce the size of the previously allocated block, and just does an
alloc, copy, free sequence internally. The problem doesn't arise
on free, it arises on the implied malloc. I would much rather
detect the problem as early as possible.
--
"I was born lazy. I am no lazier now than I was forty years
ago, but that is because I reached the limit forty years ago.
You can't go beyond possibility." -- Mark Twain
In all cases you alone are responsible for not using more memory
than you have allocated. If that value is 0, you obviously are not
allowed to use any of it. When the system returns a non-NULL value
for success, you can safely treat a return of NULL as an indication
of memory exhaustion (for at least the amount requested). It
simply keeps the treatment consistent, without special cases.
Joe Wright wrote:
> Surely realloc(nonnull, 0) cannot allocate zero bytes.
Why not? If malloc() can allocate zero bytes, why can't realloc()?
I always assumed that a malloc(0) which returned a non-null
was meant to be used to "preallocate" objects whose sizes are
not known at the time of the malloc, but still needed to be
stored as non-null pointers somewhere. The fact that the
pointers are not null provides an indication that the objects
have been preallocated. Then, presumably, later calls to
realloc() are made to complete the allocations of the objects.
Likewise, I always assumed that realloc(p,0) was meant
to "mostly" deallocate an object but keep a non-null "place
holder" for it, so that it could later either be reallocated
with a definite nonzero size, or freed completely.
As a side issue, is an implementation allowed to return
the same value (besides NULL) for all malloc(0) calls?
-drt
Why do your quotes invariably seem to remove the inter-paragraph
blank lines? It makes them hard to read, and is very annoying.
> As a side issue, is an implementation allowed to return
> the same value (besides NULL) for all malloc(0) calls?
No:
If the size of the space requested is zero, the behavior is
implementation-defined: either a null pointer is returned,
or the behavior is as if the size were some nonzero value,
except that the returned pointer shall not be used to access
an object.
--
"Am I missing something?"
--Dan Pop
That would be one way to simplify certain algorithms.
Unfortunately, without a guarantee that malloc(0) has
to succeed (so long as storage remains available), a
portable program has to take more pains, perhaps
malloc(n?n:1)
> As a side issue, is an implementation allowed to return
> the same value (besides NULL) for all malloc(0) calls?
No; the spec says that at least one byte will be
actually allocated, and there is some general statement
that no two active heap allocations will overlap.
No.
7.20.3 p1 (n1124 or N869)
If the size of the space requested is zero, the behavior is
implementation-defined: either a null pointer is returned, or the
behavior is as if the size were some nonzero value, except that
the returned pointer shall not be used to access an object.
Your "malloc(n ? n : 1)" will have problems if a macro whenever n
is an expression.
--
"The most amazing achievement of the computer software industry
is its continuing cancellation of the steady and staggering
gains made by the computer hardware industry..." - Petroski
Did you even read the previous message before responding?
> Your "malloc(n ? n : 1)" will have problems if a macro whenever n
> is an expression.
Obviously it was not a macro definition.
Yes. You stated that at least one byte would be allocated. I
disputed that.
--
Some informative links:
<http://members.fortunecity.com/nnqweb/> (newusers)
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/> (taming google)
He stated that at least one byte would be allocated if the result is
not NULL, which is correct.
Pedantically, no. However we are arguing over the density of
angels on pinheads, which is not productive.
--
"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare
Actually, yes -- it was so stipulated in the portion that you
snipped out.
Those two examples given above do not have the same behavior, which
probably was intended; on an implementation where malloc(0) returns
a non-null pointer the former passes through without returning while
the latter returns after an explicit call to free. Furthermore,
strictly speaking, the former is not strictly conforming to C90.
--
Jun, Woong (woong at icu.ac.kr)
Samsung Electronics Co., Ltd.
``All opinions expressed are mine, and do not represent
the official opinions of any organization.''
No, I didn't really think of that. Just the simplest way to deal with
realloc(,0) after and before the call.
> Furthermore, strictly speaking, the former is not strictly conforming
> to C90.
Shrug. If we are going to be that paranoid about constants like
__STDC_VERSION__ or __cplusplus, it'd be no use to introduce them at all.
--
Hallvard
> Jun Woong writes:
[...]
> >
> > Those two examples given above do not have the same behavior, which
> > probably was intended; (...)
>
> No, I didn't really think of that. Just the simplest way to deal with
> realloc(,0) after and before the call.
>
Yes, the difference really originates from a point of time when a
call to realloc with the size 0 is handled.
> > Furthermore, strictly speaking, the former is not strictly conforming
> > to C90.
>
> Shrug. If we are going to be that paranoid about constants like
> __STDC_VERSION__ or __cplusplus, it'd be no use to introduce them at all.
>
It would never cause a problem in practice. But this is comp.std.c;
I meant pedanticism with "strictly speaking."
Surely you mean "pedantry" rather than "pedanticism".
8-)}
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
> "Jun Woong" <wo...@icu.ac.kr> writes:
> [...]
> > It would never cause a problem in practice. But this is comp.std.c;
> > I meant pedanticism with "strictly speaking."
>
> Surely you mean "pedantry" rather than "pedanticism".
>
<OT>
My Korean-English dictionary says that they refer to the same
meaning. Is there any (subtle?) difference I didn't recognize?
</OT>
I think they probably mean the same thing. I was more interested in
making a joke than in strict accuracy.
> </OT>
I think they are subtly different, but I can't quite put my finger
on it. To me, pedantry implies use, while pedanticism implies
adherence to the practice.
"He indulged in pedantry in his reply"
vs
"He is a confirmed pedanticist" or "He practices pedanticism"
Added cross-post to alt.usage.english
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
> Keith Thompson wrote:
> > "Jun Woong" <wo...@icu.ac.kr> writes:
> >> Keith Thompson wrote:
> >>> "Jun Woong" <wo...@icu.ac.kr> writes:
> >>> [...]
> >>>> It would never cause a problem in practice. But this is comp.std.c;
> >>>> I meant pedanticism with "strictly speaking."
> >>>
> >>> Surely you mean "pedantry" rather than "pedanticism".
> >>
> >> My Korean-English dictionary says that they refer to the same
> >> meaning. Is there any (subtle?) difference I didn't recognize?
> >
> > I think they probably mean the same thing. I was more interested
> > in making a joke than in strict accuracy.
>
> I think they are subtly different, but I can't quite put my finger
> on it. To me, pedantry implies use, while pedanticism implies
> adherence to the practice.
>
> "He indulged in pedantry in his reply"
> vs
> "He is a confirmed pedanticist" or "He practices pedanticism"
>
Oh, then, as Keith pointed out, "pedanticism" in my post should read
as "pedantry." ;-)
> "Jun Woong" <wo...@icu.ac.kr> writes:
> [...]
>> It would never cause a problem in practice. But this is comp.std.c;
>> I meant pedanticism with "strictly speaking."
>
> Surely you mean "pedantry" rather than "pedanticism".
Your spelling is fine, but your pronunciation is incorrect.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Douglas A. Gwyn wrote:
> No; the spec says that at least one byte will be
> actually allocated, and there is some general statement
> that no two active heap allocations will overlap.
I didn't think so.
Another side issue. 7.20.3 says:
The pointer returned if the allocation succeeds is suitably aligned
so that it may be assigned to a pointer to any type of object [A]
and then used to access such an object or an array of such objects
in the space allocated
I assume we could insert at [A] the phrase:
having a size not greater than the allocated space
In other words, if I malloc two bytes, I can't expect that I can store
"any type of object" in the space (such as a 4-byte float). Nor should
I expect that the space allocated is "suitably aligned" for any object
type larger than two bytes, right?
-drt
No, I think the standard does promise that this is defined:
float *foo = malloc( 1 );
Why make such an assumption; it is counter to what the standard already
says.
> In other words, if I malloc two bytes, I can't expect that I can store
> "any type of object" in the space (such as a 4-byte float). Nor should
> I expect that the space allocated is "suitably aligned" for any object
> type larger than two bytes, right?
AIUI, the alignment is absolute. If malloc returns a non-NULL pointer,
it is aligned suitably for *any* type, period. I see nothing undefined
about:
double *d = malloc(1);
Of course, if sizeof(double) is greater than 1, then dereferencing or
incrementing d would be undefined.
--
Clark S. Cox III
clar...@gmail.com
>AIUI, the alignment is absolute. If malloc returns a non-NULL pointer,
>it is aligned suitably for *any* type, period. I see nothing undefined
>about:
>
> double *d = malloc(1);
>
>Of course, if sizeof(double) is greater than 1, then dereferencing or
>incrementing d would be undefined.
But if sizeof(double) is greater than one, how can you observe whether
or not the address is adequately aligned for a double? All conforming
programs work even if the alignment is wrong.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
That's a different requirement. The intent is to have the same
more-stringent alignment requirement even for pointers to tiny
allocations (which would be a natural property of most malloc
implementations anyway).
Of course the "any type ... and then used to access" is meant
to be subject to the requirement that the accessed object
representation lie entirely within the array of bytes
allocated (which cannot be assumed to be more than the size
requested). That probably falls out of generic requirements
elsewhere in the standard.
> In article <12r2682...@corp.supernews.com>,
> Clark S. Cox III <clar...@gmail.com> wrote:
>
>>AIUI, the alignment is absolute. If malloc returns a non-NULL pointer,
>>it is aligned suitably for *any* type, period. I see nothing undefined
>>about:
>>
>> double *d = malloc(1);
>>
>>Of course, if sizeof(double) is greater than 1, then dereferencing or
>>incrementing d would be undefined.
>
> But if sizeof(double) is greater than one, how can you observe whether
> or not the address is adequately aligned for a double? All conforming
> programs work even if the alignment is wrong.
Converting to a pointer type for which the pointer value is
misaligned yields undefined behavior in itself. See C99 6.3.2.3:
A pointer to an object or incomplete type may be converted
to a pointer to a different object or incomplete type. If
the resulting pointer is not correctly aligned57) for the
pointed-to type, the behavior is undefined.
Thus, "double *d = malloc(1);" is well-defined, but "char c;
double d = &c;" is not.
--
Ben Pfaff
b...@cs.stanford.edu
http://benpfaff.org
>>>Of course, if sizeof(double) is greater than 1, then dereferencing or
>>>incrementing d would be undefined.
>> But if sizeof(double) is greater than one, how can you observe whether
>> or not the address is adequately aligned for a double? All conforming
>> programs work even if the alignment is wrong.
>Converting to a pointer type for which the pointer value is
>misaligned yields undefined behavior in itself.
On a system where that in fact generates an error, malloc(1) could not
returned an insufficiently aligned address. But on a system where
that is not the case, malloc(1) *is* sufficiently aligned for all the
things you can legally do with it. That is, these systems behave *as
if* malloc(1) was sufficiently aligned for a double.
> In article <87y7nys...@blp.benpfaff.org>,
> Ben Pfaff <b...@cs.stanford.edu> wrote:
>
>>>>Of course, if sizeof(double) is greater than 1, then dereferencing or
>>>>incrementing d would be undefined.
>
>>> But if sizeof(double) is greater than one, how can you observe whether
>>> or not the address is adequately aligned for a double? All conforming
>>> programs work even if the alignment is wrong.
>
>>Converting to a pointer type for which the pointer value is
>>misaligned yields undefined behavior in itself.
>
> On a system where that in fact generates an error, malloc(1) could not
> returned an insufficiently aligned address. But on a system where
> that is not the case, malloc(1) *is* sufficiently aligned for all the
> things you can legally do with it. That is, these systems behave *as
> if* malloc(1) was sufficiently aligned for a double.
I don't think that contradicts anything I said, although it does
clarify it.
--
Here's a tip: null pointers don't have to be *dull* pointers!
I think I agree.
Suppose sizeof(double)==8, and double requires 8-byte alignment. But
suppose that converting a misaligned char* pointer to double* (which
invokes undefined behavior) simply copies the bit pattern, and never
causes anything "bad" to happen. In other words, attempting to access
a misaligned double object can crash your program, but constructing a
misaligned pointer to double cannot. (These are assumptions about a
particular hypothetical implementation.)
Then the standard's definition of malloc() explicitly requires
double *ptr = malloc(1);
(assuming it succeeds) to set ptr to a value that's properly aligned
(i.e., 8-byte aligned) for type double -- but there's no way for a
portable program to detect a violation of this requirement. So I
think the "as if" rule applies.
If a tree is misaligned in a forest and nobody can access it, does it
invoke undefined behavior?
Note that if the result of malloc(1) is misaligned, then
realloc(ptr, sizeof(double))
will not be able to expand the allocated space in place; it must
allocate a *new* properly aligned 8-byte block. This doesn't argue
that malloc(1) can't yield a misaligned pointer, merely that the
implementation must take some extra care if it does so.
Well, if you assume nothing can go wrong then of course you can
conclude that nothing can go wrong. However, a not-strictly-
conforming program could inspect the returned address in an
implementation-dependent way and still determine that it has
improper alignment, taking a branch that a conforming
implementation must not allow to happen.
The requirements on a conforming implementation are not limited
to compilation of s.c. programs.
Um, where did I mention strictly conforming programs?
Any code that examines a pointer value and determines whether it's
properly aligned must depend on (at least) implementation-defined
behavior. For example, it might convert the pointer value to an
integer type and examine the low-order bits, or convert it to a string
using sprintf("%p", ptr); both conversions are implementation-defined.
But I don't see anything that requires an implementation to define
these conversions in a way that allows a program to determine the
pointer value's alignment. I can imagine an implementation in which
malloc(1) returns a misaligned pointer, but no program, using the
standard and the implementation's required documentation, can prove
this.
Before we get too far into this, let me say that *this* particular
issue is, in my opinion, no big deal. I think there's a requirement
in the standard that can, for some implementations, be violated more
or less undetectably. It's an interesting theoretical tidbit, but I
don't think there are any significant consequences.
I find that OED doesn't make CBF's distinction, and its most recent
example of "pedanticism" came from Roy Jenkins. Even if that in itself
isn't enough to recommend using "pedantry" instead, I think the word is
a syllable too far. I suppose we could support the term for something
like "holding to pedantry as a way of life", but I'd want to see some
credible examples.
--
Mike.
--
Posted via a free Usenet account from http://www.teranews.com
<snip>
> I find that OED doesn't make CBF's distinction, and its most recent
> example of "pedanticism" came from Roy Jenkins. Even if that in itself
> isn't enough to recommend using "pedantry" instead, I think the word is
> a syllable too far. I suppose we could support the term for something
> like "holding to pedantry as a way of life", but I'd want to see some
> credible examples.
How about "the regulars of comp.lang.c believe in pedanticism"? ;-)
--
Flash Gordon
In short words (you probably all know that on comp.std.c): Hardware
doesn't dictate at all what is in a C implementation. The
documentation does it.
</off-topic>
However, I would like to point out that this piece of code is (maybe)
portable. I'm not sure since it's "border-line".
char* p0=malloc(1),*p1=malloc(sizeof(double)-1);
if (p0 && p1 && p0+1==p1) {
*((double*)p0)=42.3; /* here, I'm not sure that this statement is
valid... If it's invalid, I would like to know why */
}
free(p0);free(p1);
p0+1 is a valid expression (pointer to one past the last element of an
array).
p0+1 == p1 is a valid expression. You can compare any two pointers...
result of this comparison is unspecified.
Of course, it's very likely not to return true!
So, if an implementation makes this p0+1==p1 expression always return
0 (for example, allocating one extra byte when malloc'ing, or using
bound checks, or any other reliable mean), malloc can return a pointer
mis-aligned at hardware level (except if the documentation of this
compiler provides a mean to detect this mis-alignment).
In that case, the "as-if" rule is respected.
If you mean strict conformance to the standard by "valid," I can't
believe you said that. p0 and p1 point to two distinct objects which
happen to be adjacent in the sense of the pointer arithmetic that
constitutes the logical address space for C programs. I see nothing
from the standard to make it differ from
T *p = malloc(sizeof(*p)-1);
*p = valid_value_for_type_T;
Of course, the standard needs be revised to surely say
"non-conformance" to this kind of code. Though your code would be
fairly portable in practice.
> free(p0);free(p1);
>
> p0+1 is a valid expression (pointer to one past the last element of an
> array).
> p0+1 == p1 is a valid expression. You can compare any two pointers...
> result of this comparison is unspecified.
>
> Of course, it's very likely not to return true!
>
> So, if an implementation makes this p0+1==p1 expression always return
> 0 (for example, allocating one extra byte when malloc'ing, or using
> bound checks, or any other reliable mean), malloc can return a pointer
> mis-aligned at hardware level (except if the documentation of this
> compiler provides a mean to detect this mis-alignment).
If there is NO mean to detect a misaligned pointer on an
implementation, I think it means simply there is nothing called
"misaligned pointers" on it.