Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #73265 > unrolled thread
| Started by | "Morten W. Petersen" <morphex@gmail.com> |
|---|---|
| First post | 2015-10-19 00:53 -0700 |
| Last post | 2015-10-22 06:06 +0000 |
| Articles | 20 on this page of 80 — 23 participants |
Back to article view | Back to comp.lang.c
Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-19 00:53 -0700
Re: Pointers as error values gazelle@shell.xmission.com (Kenny McCormack) - 2015-10-19 08:26 +0000
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-19 02:27 -0700
Re: Pointers as error values Richard Damon <Richard@Damon-Family.org> - 2015-10-19 23:38 -0400
Re: Pointers as error values jacobnavia <jacob@jacob.remcomp.fr> - 2015-10-19 10:34 +0200
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-19 02:29 -0700
Re: Pointers as error values mark.bluemel@gmail.com - 2015-10-19 05:53 -0700
Re: Pointers as error values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-19 10:00 +0000
Re: Pointers as error values Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-10-19 14:00 +0000
Re: Pointers as error values gwowen <gwowen@gmail.com> - 2015-10-19 08:02 -0700
Re: Pointers as error values James Kuyper <jameskuyper@verizon.net> - 2015-10-19 11:53 -0400
Re: Pointers as error values Ken Brody <kenbrody@spamcop.net> - 2015-10-19 11:25 -0400
Re: Pointers as error values supercat@casperkitty.com - 2015-10-19 08:41 -0700
Re: Pointers as error values Keith Thompson <kst-u@mib.org> - 2015-10-19 08:59 -0700
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-21 07:32 +0200
Re: Pointers as error values Ian Collins <ian-news@hotmail.com> - 2015-10-21 19:17 +1300
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-21 08:31 +0200
Re: Pointers as error values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-21 12:46 +0100
Re: Pointers as error values Robert Wessel <robertwessel2@yahoo.com> - 2015-10-21 09:35 -0500
Re: Pointers as error values Ken Brody <kenbrody@spamcop.net> - 2015-10-21 15:24 -0400
Re: Pointers as error values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-22 05:44 +0000
Re: Pointers as error values Keith Thompson <kst-u@mib.org> - 2015-10-21 10:41 -0700
Re: Pointers as error values supercat@casperkitty.com - 2015-10-21 11:28 -0700
Re: Pointers as error values John Temples <usenet@xargs-spam.com> - 2015-10-21 17:45 +0000
Re: Pointers as error values James Kuyper <jameskuyper@verizon.net> - 2015-10-21 14:15 -0400
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-29 16:59 +0100
Re: Pointers as error values supercat@casperkitty.com - 2015-10-29 12:35 -0700
Re: Pointers as error values raltbos@xs4all.nl (Richard Bos) - 2015-10-29 21:45 +0000
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-30 06:09 +0100
Re: Pointers as error values Rosario19 <Ros@invalid.invalid> - 2015-10-30 08:59 +0100
Re: Pointers as error values Rosario19 <Ros@invalid.invalid> - 2015-10-30 09:07 +0100
Re: Pointers as error values Rosario19 <Ros@invalid.invalid> - 2015-10-30 09:38 +0100
Re: Pointers as error values Rosario19 <Ros@invalid.invalid> - 2015-10-30 09:40 +0100
Re: Pointers as error values Robert Wessel <robertwessel2@yahoo.com> - 2015-10-30 04:56 -0500
Re: Pointers as error values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-30 11:00 +0000
Re: Pointers as error values Robert Wessel <robertwessel2@yahoo.com> - 2015-10-29 23:48 -0500
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-30 11:05 +0100
Re: Pointers as error values Richard Damon <Richard@Damon-Family.org> - 2015-10-30 07:45 -0400
Re: Pointers as error values Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-30 05:04 -0700
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-30 16:09 +0100
Re: Pointers as error values Keith Thompson <kst-u@mib.org> - 2015-10-30 11:16 -0700
Re: Pointers as error values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-30 20:58 +0000
Re: Pointers as error values Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-10-30 17:12 -0400
Re: Pointers as error values supercat@casperkitty.com - 2015-10-30 14:54 -0700
Re: Pointers as error values Robert Wessel <robertwessel2@yahoo.com> - 2015-10-30 18:48 -0500
Re: Pointers as error values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-01 04:00 +0000
Re: Pointers as error values Robert Wessel <robertwessel2@yahoo.com> - 2015-11-01 01:24 -0500
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-31 20:35 +0100
Re: Pointers as error values supercat@casperkitty.com - 2015-10-31 13:33 -0700
Re: Pointers as error values Richard Damon <Richard@Damon-Family.org> - 2015-10-30 22:19 -0400
Re: Pointers as error values supercat@casperkitty.com - 2015-10-30 08:22 -0700
Re: Pointers as error values Geoff <geoff@invalid.invalid> - 2015-10-30 13:11 -0700
Re: Pointers as error values Geoff <geoff@invalid.invalid> - 2015-10-30 13:23 -0700
Re: Pointers as error values Geoff <geoff@invalid.invalid> - 2015-10-21 11:13 -0700
Re: Pointers as error values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-21 20:31 +0100
Re: Pointers as error values Geoff <geoff@invalid.invalid> - 2015-10-22 07:13 -0700
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-26 07:16 +0100
Re: Pointers as error values Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-10-26 09:37 +0000
Re: Pointers as error values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-22 05:38 +0000
Re: Pointers as error values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-22 13:51 +0100
Re: Pointers as error values Keith Thompson <kst-u@mib.org> - 2015-10-22 08:29 -0700
Re: Pointers as error values supercat@casperkitty.com - 2015-10-22 09:21 -0700
Re: Pointers as error values Keith Thompson <kst-u@mib.org> - 2015-10-22 10:52 -0700
Re: Pointers as error values "Morten W. Petersen" <morphex@gmail.com> - 2015-10-26 07:20 +0100
Re: Pointers as error values Keith Thompson <kst-u@mib.org> - 2015-10-26 08:09 -0700
Re: Pointers as error values supercat@casperkitty.com - 2015-10-26 08:40 -0700
Re: Pointers as error values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-26 20:02 +0000
Re: Pointers as error values supercat@casperkitty.com - 2015-10-26 13:56 -0700
Re: Pointers as error values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-22 21:58 +0000
Re: Pointers as error values James Kuyper <jameskuyper@verizon.net> - 2015-10-22 19:12 -0400
Re: Pointers as error values asetofsymbols@gmail.com - 2015-10-22 18:36 -0700
Re: Pointers as error values asetofsymbols@gmail.com - 2015-10-29 12:47 -0700
Re: Pointers as error values Lőrinczy Zsigmond <nospam@for.me> - 2015-10-20 17:06 +0200
Re: Pointers as error values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-20 19:45 +0100
Re: Pointers as error values supercat@casperkitty.com - 2015-10-20 14:19 -0700
Re: Pointers as error values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-21 05:28 +0000
Re: Pointers as error values supercat@casperkitty.com - 2015-10-21 05:48 -0700
Re: Pointers as error values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-22 05:52 +0000
Re: Pointers as error values Ken Brody <kenbrody@spamcop.net> - 2015-10-21 15:19 -0400
Re: Pointers as error values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-22 06:06 +0000
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2015-10-22 05:44 +0000 |
| Message-ID | <n09t4c$emk$1@speranza.aioe.org> |
| In reply to | #73512 |
Ken Brody <kenbrody@spamcop.net> wrote: > On 10/21/2015 10:35 AM, Robert Wessel wrote: > [...] >> Most more recent OSs have been designed with C in mind, and take some >> pains to make addresses in low core unusable, at least on systems with >> virtual memory (*nix, for example, usually makes the first page >> unaddressable, Windows make the first 64KB unaddressable). > I have seen at least one *nix implementation which makes the first page > (4K?) of memory all zeros, read-only. Dereferencing a NULL pointer (for > read) of any type will return zero, and all of the str*() functions will see > a NULL pointer as an empty string. (And attemping to write there will still > SEGV.) I believe there are some system that have a page full of zeros, which may or may not be at address zero. Any request to allocate memory is mapped to (some copies of) that page, but no actual memory is allocated. Any attempt to write such memory results in a new page being allocated, mapped as appropriate, and the write is retried. Avoids wasted allocation for memory that won't be used. Also surprises people who write benchmarks like: unsigned char *s, *t; s=malloc(1000000000); t=malloc(1000000000); memcpy(s, t, 1000000000); -- glen > Whether this is a "good" or "bad" idea is left as an exercise for the reader. >
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-10-21 10:41 -0700 |
| Message-ID | <lntwpkw249.fsf@kst-u.example.com> |
| In reply to | #73450 |
"Morten W. Petersen" <morphex@gmail.com> writes:
> On 19.10.2015 17:59, Keith Thompson wrote:
>> "Morten W. Petersen" <morphex@gmail.com> writes:
>>> I was thinking the other day, that NULL pointers indicate an error.
>>> That got me wondering, is it possible to use a low number range as
>>> valid error indicators?
>>
>> A null pointer doesn't necessarily indicate an error. Sometimes it's a
>> valid result.
>>
>>> That is, could for example numbers from 1 to 7 be safely used as error
>>> indicators from a function that should return a pointer?
>>
>> Not 100% portably. A small non-zero integer converted to a pointer
>> type is unlikely to match a valid pointer value, but there's no
>> guarantee. Even accessing an invalid pointer (without dereferencing
>> it) can have undefined behavior.
>
> Hmm, OK. That dereferencing wouldn't work was expected, but why would
> working with an address value not work?
>
> What is a real-life example where using 1-7 as pointer return values
> would not work?
I don't have a real-life example, and it's entirely possible that you
could write code that assumes (void*)1, (void*)2, et al are distinct
values that can be used and compared safely as long as you don't try to
dereference them and get away with it. But such code goes beyond the
behavior guaranteed by the standard.
This code:
void *p0 = NULL;
void *p1 = (void*)1;
puts(p0 == p1 ? "equal" : "unequal");
will *probably* print "unequal", but its behavior is not defined by the
standard. In principle, it could print "equal" if the implementation
uses the same representation for a null pointer and for (void*)1. Or it
could crash if loading an invalid pointer into a register causes a trap.
[...]
> Yes, using static objects is a nice, clean alternative, but would
> require checking if each and every of these static objects match.
If the static objects are elements of an array, you can at least use a
loop to compare a pointer for equality to each element's address rather
than coding each comparison explicitly.
> So far I'd like to go for something like what Jacob suggested earlier,
> a simple less-than comparison.
If you define macros like:
#define P1 ((void*)1)
#define P2 ((void*)2)
/* ... */
#define P7 ((void*)7)
it's likely that
(p >= P1 && p <= P7)
will yield the same result as
(p == P1 || p == P2 || ... || p == P7)
If you want to depend on that, feel free to do so. Just be aware that
you're going beyond what the standard guarantees.
Incidentally, I've worked on systems where the above would mostly work,
but it would be possible to construct a pointer p such that
(P1 < p && p < P2).
Such a pointer would be unlikely to be created accidentally, so the
scheme would probably still work.
(It's also possible that an optimizer might transform your code based on
the assumption that its behavior is defined.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-21 11:28 -0700 |
| Message-ID | <b5df34ca-5077-4f69-9697-309c0c67afaf@googlegroups.com> |
| In reply to | #73503 |
On Wednesday, October 21, 2015 at 12:41:37 PM UTC-5, Keith Thompson wrote:
> This code:
>
> void *p0 = NULL;
> void *p1 = (void*)1;
> puts(p0 == p1 ? "equal" : "unequal");
>
> will *probably* print "unequal", but its behavior is not defined by the
> standard. In principle, it could print "equal" if the implementation
> uses the same representation for a null pointer and for (void*)1. Or it
> could crash if loading an invalid pointer into a register causes a trap.
Or it could cause a compiler that knows that its integer-to-pointer
conversion technique will never turn the value 1 into an odd pointer
to decide that if receipt of certain input would cause the above code
to be executed, the compiler would be entitled to ignore *any* code
which would have no effect if such input is not received.
Thus, if the above code were unconditionally within function "foo()"
with no preceding side-effects, a compiler given:
if (should_launch_missiles())
launch_missiles();
foo();
would be entitled to replace the code with:
should_launch_missiles();
launch_missiles();
since the C Standard would impose no requirements upon program behavior
if should_launch_missiles were to return zero, the compiler would be under
no obligation not to call launch_missiles in that case; making the call
to launch_missiles() unconditional thus allows the compiler to generate
code which more efficiently complies with the Standard's requirements.
While it used to be pretty well expected and accepted that in cases where
a platform would have a clear "natural meaning" for some action but the
Standard imposes no requirements, compilers should perform the natural
action for the underlying platform absent a compelling reason to do
otherwise(*) today's compiler writers no longer feel bound by that
tradition. In many cases, code exploiting natural platform behaviors could
be more efficient and easier to read than strictly-conforming code, but
many compiler writers do not recognize any value in letting programmers
exploit natural platform behaviors which aren't recognized by the Standard.
(*) If a programmer enables a "trap null-pointer operations" option, then
even on hardware that doesn't trap null-pointer accesses, the fact
that the programmer explicitly requested the compiler to trap on
attempts to perform invalid operations on null-pointers would be a
compelling reason for a compiler to do so.
[toc] | [prev] | [next] | [standalone]
| From | John Temples <usenet@xargs-spam.com> |
|---|---|
| Date | 2015-10-21 17:45 +0000 |
| Message-ID | <slrnn2fjpm.dkf.usenet@xargs-spam.com> |
| In reply to | #73450 |
On 2015-10-21, Morten W. Petersen <morphex@gmail.com> wrote: > On 19.10.2015 17:59, Keith Thompson wrote: >> "Morten W. Petersen" <morphex@gmail.com> writes: >>> That got me wondering, is it possible to use a low number range as >>> valid error indicators? >>> That is, could for example numbers from 1 to 7 be safely used as error >>> indicators from a function that should return a pointer? >> >> Not 100% portably. A small non-zero integer converted to a pointer >> type is unlikely to match a valid pointer value, but there's no >> guarantee. Even accessing an invalid pointer (without dereferencing >> it) can have undefined behavior. > > Hmm, OK. That dereferencing wouldn't work was expected, but why would > working with an address value not work? > > What is a real-life example where using 1-7 as pointer return values > would not work? There are many 8- and 16-bit platforms that have linear memory starting at address 0. The compiler could place an object at address 7, so (void*)7 would be a valid pointer to an object. You would have to reserve the memory at addresses 1-7 to prevent that from happening.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-10-21 14:15 -0400 |
| Message-ID | <n08kk2$a6d$1@dont-email.me> |
| In reply to | #73504 |
On 10/21/2015 01:45 PM, John Temples wrote: ... > There are many 8- and 16-bit platforms that have linear memory > starting at address 0. The compiler could place an object at address > 7, so (void*)7 would be a valid pointer to an object. You would have > to reserve the memory at addresses 1-7 to prevent that from happening. The normal way you reserve space in C is to declare a named object to occupy that space. C doesn't have the option of specifying the location for an object, but you don't really need to. It doesn't really matter whether its at address 7 or not - just use &overflow_error, rather than (void*)7. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | "Morten W. Petersen" <morphex@gmail.com> |
|---|---|
| Date | 2015-10-29 16:59 +0100 |
| Message-ID | <n0tfor$ek6$1@speranza.aioe.org> |
| In reply to | #73507 |
On 21.10.2015 20:15, James Kuyper wrote: > On 10/21/2015 01:45 PM, John Temples wrote: > ... >> There are many 8- and 16-bit platforms that have linear memory >> starting at address 0. The compiler could place an object at address >> 7, so (void*)7 would be a valid pointer to an object. You would have >> to reserve the memory at addresses 1-7 to prevent that from happening. > > The normal way you reserve space in C is to declare a named object to > occupy that space. C doesn't have the option of specifying the location > for an object, but you don't really need to. It doesn't really matter > whether its at address 7 or not - just use &overflow_error, rather than > (void*)7. Now you're talking about defining a variable and checking that address, right? From what I've gathered in this entire thread, it isn't possible to use the addresses 1-7 safely to indicate an error. However, I could declare an array of 8 char for example, and check the return value against addresses in that range. -Morten
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-10-29 12:35 -0700 |
| Message-ID | <9c00a627-ce2b-41bf-a970-c8672a25d914@googlegroups.com> |
| In reply to | #74180 |
On Thursday, October 29, 2015 at 10:59:37 AM UTC-5, Morten W. Petersen wrote:
> However, I could declare an array of 8 char for example, and check
> the return value against addresses in that range.
Only if your pointer is a char*. Otherwise you'd need to use a type which
satisfies the alignment of your pointer type; any pointer value which does
not satisfy the alignment of the pointer type holding it is to be regarded
as a trap representation, and doing anything with a trap representation
invokes Undefined Behavior.
The issue isn't just one of compilers being capricious. Consider the function:
void copy_uint64_t(uint64_t *dest, uint64_t*src)
{
memcpy(dest, src, sizeof (uint64_t));
}
void test(void)
{
uint64_t foo[4] = {123};
char *foo1 = foo;
char *foo2 = foo1 + sizeof (uint64_t) + 1;
memcpy(foo2, foo1, sizeof (uint64_t)); // Legal
copy_uint64_t((uint64_t*)foo2, (uint64_t*)foo1); // Likely to fail
}
Even though memcpy() uses void*, and may generally be used to copy objeccts
with any alignment, a compiler would be allowed to replace the memcpy within
the copy_int function with *dest=*src; provided that it did not enforce the
rules about type aliasing. On systems which require uint64_t to be aligned,
however, the code will fail because foo2 will not be properly aligned for
use as a uint64_t*. The C Standard doesn't say anything about why the
memcpy would be allowed to fail *except* that the value passed to "dest"
is a trap representation; that is sufficient to justify anything that may
happen as a result.
[toc] | [prev] | [next] | [standalone]
| From | raltbos@xs4all.nl (Richard Bos) |
|---|---|
| Date | 2015-10-29 21:45 +0000 |
| Message-ID | <56329244.13725875@news.xs4all.nl> |
| In reply to | #74196 |
supercat@casperkitty.com wrote: > On Thursday, October 29, 2015 at 10:59:37 AM UTC-5, Morten W. Petersen wrote: > > However, I could declare an array of 8 char for example, and check > > the return value against addresses in that range. > > Only if your pointer is a char*. Otherwise you'd need to use a type which > satisfies the alignment of your pointer type; any pointer value which does > not satisfy the alignment of the pointer type holding it is to be regarded > as a trap representation, and doing anything with a trap representation > invokes Undefined Behavior. You could allocate an array of eight void *s, malloc() a single byte** of memory for each, and compare to that. Each pointer is guaranteed to be unique, different from all other valid objects; each pointer is guaranteed not to be valid (but do remember to check for null returns from malloc(), uproariously unlikely as they may be in this case); and crucially, being void *s and returns from malloc(), each is guaranteed to be maximally aligned. _Or_ you could be sensible and not abuse different pointer values as error indicators. Richard ** (someone's going to speculate that a single malloc()'ed byte needn't be properly aligned for larger objects, but IMAO that's only true if no program can tell the difference, while in this case it's the entire point of the exercise that yours can)
[toc] | [prev] | [next] | [standalone]
| From | "Morten W. Petersen" <morphex@gmail.com> |
|---|---|
| Date | 2015-10-30 06:09 +0100 |
| Message-ID | <n0uu22$d51$1@speranza.aioe.org> |
| In reply to | #74205 |
On 29.10.2015 22:45, Richard Bos wrote:
> supercat@casperkitty.com wrote:
>
>> On Thursday, October 29, 2015 at 10:59:37 AM UTC-5, Morten W. Petersen wrote:
>>> However, I could declare an array of 8 char for example, and check
>>> the return value against addresses in that range.
>>
>> Only if your pointer is a char*. Otherwise you'd need to use a type which
>> satisfies the alignment of your pointer type; any pointer value which does
>> not satisfy the alignment of the pointer type holding it is to be regarded
>> as a trap representation, and doing anything with a trap representation
>> invokes Undefined Behavior.
>
> You could allocate an array of eight void *s, malloc() a single byte**
> of memory for each, and compare to that. Each pointer is guaranteed to
> be unique, different from all other valid objects; each pointer is
> guaranteed not to be valid (but do remember to check for null returns
> from malloc(), uproariously unlikely as they may be in this case); and
> crucially, being void *s and returns from malloc(), each is guaranteed
> to be maximally aligned.
>
> _Or_ you could be sensible and not abuse different pointer values as
> error indicators.
OK. But then it should be OK to allocate
void *pointers[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
And do
void *pointer = some_function();
if (pointer >= &pointers && pointer <= &pointers+8) {
Some code here
}
Right?
-Morten
[toc] | [prev] | [next] | [standalone]
| From | Rosario19 <Ros@invalid.invalid> |
|---|---|
| Date | 2015-10-30 08:59 +0100 |
| Message-ID | <od763b5tj5kmg2tacq27la0rp5bt9jdof8@4ax.com> |
| In reply to | #74228 |
On Fri, 30 Oct 2015 06:09:30 +0100, "Morten W. Petersen" wrote:
>On 29.10.2015 22:45, Richard Bos wrote:
>> supercat@casperkitty.com wrote:
>>
>>> On Thursday, October 29, 2015 at 10:59:37 AM UTC-5, Morten W. Petersen wrote:
>>>> However, I could declare an array of 8 char for example, and check
>>>> the return value against addresses in that range.
>>>
>>> Only if your pointer is a char*. Otherwise you'd need to use a type which
>>> satisfies the alignment of your pointer type; any pointer value which does
>>> not satisfy the alignment of the pointer type holding it is to be regarded
>>> as a trap representation, and doing anything with a trap representation
>>> invokes Undefined Behavior.
>>
>> You could allocate an array of eight void *s, malloc() a single byte**
>> of memory for each, and compare to that. Each pointer is guaranteed to
>> be unique, different from all other valid objects; each pointer is
>> guaranteed not to be valid (but do remember to check for null returns
>> from malloc(), uproariously unlikely as they may be in this case); and
>> crucially, being void *s and returns from malloc(), each is guaranteed
>> to be maximally aligned.
>>
>> _Or_ you could be sensible and not abuse different pointer values as
>> error indicators.
>
>OK. But then it should be OK to allocate
>
>void *pointers[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
>
>And do
>
>void *pointer = some_function();
>if (pointer >= &pointers && pointer <= &pointers+8) {
> Some code here
>}
>
>Right?
>
>-Morten
i think he means something as:
// as global varable is language allow that initialitation
int pGlo[]={0,1,2,3,4,5,6,7};
void *pointers[]=
{pGlo, pGlo+1, pGlo+2, pGlo+3, pGlo+5, pGlo+6, pGlo+6, pGlo+7};
.....
// in a function
*pointer = some_function();
if (pointers[0]<=pointer && pointer<=pointers[7]) {
Some error code here
}
--------
if the sys not allow that initialization than one could do something
as
int pGlo[]={0,1,2,3,4,5,6,7};
void *pointers[8];
void initP(void){int i; for(i=0; i<8; ++i) pointers[i]=pGlo+i;}
one call in the main first of all one time only initP() function
and than
one can write in a function
void* p = some_function();
if (pointers[0]<=p && p<=pointers[7]) {
Some error code here
}
but for me the way is instead this
i32 f(type** p, arguments)
{int i;
....
if(p==0) return -1;
// in call f(&pnt, argument)
for(i=0; i<n; ++i) // or *p=malloc(size) this change pnt
(*p)[i]=0; // this change what point pnt
}
one cal them as in
type *p;
i32 re;
re=f(&p, args);
//here the value of pointer p should be changed from f
// f fill the pointer p with its result
// re is the error code result
[toc] | [prev] | [next] | [standalone]
| From | Rosario19 <Ros@invalid.invalid> |
|---|---|
| Date | 2015-10-30 09:07 +0100 |
| Message-ID | <a8963b5dkkq0me7f1b8mn1c0p1s93cskkl@4ax.com> |
| In reply to | #74235 |
On Fri, 30 Oct 2015 08:59:26 +0100, Rosario19 wrote:
>int pGlo[]={0,1,2,3,4,5,6,7};
>void *pointers[]=
> {pGlo, pGlo+1, pGlo+2, pGlo+3, pGlo+5, pGlo+6, pGlo+6, pGlo+7};
>.....
>
>// in a function
>*pointer = some_function();
the last line has to be: pointer=some_function();
[toc] | [prev] | [next] | [standalone]
| From | Rosario19 <Ros@invalid.invalid> |
|---|---|
| Date | 2015-10-30 09:38 +0100 |
| Message-ID | <ksa63b50duaj4093u660clpi5ltsu6j9pe@4ax.com> |
| In reply to | #74235 |
On Fri, 30 Oct 2015 08:59:26 +0100, Rosario19 wrote:
>i think he means something as:
>
>// as global varable is language allow that initialitation
>int pGlo[]={0,1,2,3,4,5,6,7};
>void *pointers[]=
> {pGlo, pGlo+1, pGlo+2, pGlo+3, pGlo+5, pGlo+6, pGlo+6, pGlo+7};
>.....
>
>// in a function
>*pointer = some_function();
>
>if (pointers[0]<=pointer && pointer<=pointers[7]) {
> Some error code here
> }
read the Robert Wessel post remain possibly portably right only
int pGlo[]={0,1,2,3,4,5,6,7};
int (*ponters)[]=
{pGlo, pGlo+1, pGlo+2, pGlo+3, pGlo+5, pGlo+6, pGlo+6, pGlo+7};
.....
// in a function
pres = some_function();
for(i=0;i<8; ++i)
if(pres=pointers[i]) {
Some error code here
}
[toc] | [prev] | [next] | [standalone]
| From | Rosario19 <Ros@invalid.invalid> |
|---|---|
| Date | 2015-10-30 09:40 +0100 |
| Message-ID | <a6b63bpppb5nc2ijr2tm4jkqpojdrl6hv4@4ax.com> |
| In reply to | #74242 |
On Fri, 30 Oct 2015 09:38:27 +0100, Rosario19 <Ros@invalid.invalid>
wrote:
>On Fri, 30 Oct 2015 08:59:26 +0100, Rosario19 wrote:
>
>>i think he means something as:
>>
>>// as global varable is language allow that initialitation
>>int pGlo[]={0,1,2,3,4,5,6,7};
>>void *pointers[]=
>> {pGlo, pGlo+1, pGlo+2, pGlo+3, pGlo+5, pGlo+6, pGlo+6, pGlo+7};
>>.....
>>
>>// in a function
>>*pointer = some_function();
>>
>>if (pointers[0]<=pointer && pointer<=pointers[7]) {
>> Some error code here
>> }
>
>read the Robert Wessel post remain possibly portably right only
>
>int pGlo[]={0,1,2,3,4,5,6,7};
>int (*ponters)[]=
> {pGlo, pGlo+1, pGlo+2, pGlo+3, pGlo+5, pGlo+6, pGlo+6, pGlo+7};
>.....
>
>// in a function
>pres = some_function();
>
>for(i=0;i<8; ++i)
> if(pres=pointers[i]) {
^^^^^^^^^
if(pres==pointers[i]){
> Some error code here
> }
>
>
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2015-10-30 04:56 -0500 |
| Message-ID | <pcf63bp2d0mpf7j7fpoitgvud2vjt18f6q@4ax.com> |
| In reply to | #74228 |
On Fri, 30 Oct 2015 06:09:30 +0100, "Morten W. Petersen"
<morphex@gmail.com> wrote:
>On 29.10.2015 22:45, Richard Bos wrote:
>> supercat@casperkitty.com wrote:
>>
>>> On Thursday, October 29, 2015 at 10:59:37 AM UTC-5, Morten W. Petersen wrote:
>>>> However, I could declare an array of 8 char for example, and check
>>>> the return value against addresses in that range.
>>>
>>> Only if your pointer is a char*. Otherwise you'd need to use a type which
>>> satisfies the alignment of your pointer type; any pointer value which does
>>> not satisfy the alignment of the pointer type holding it is to be regarded
>>> as a trap representation, and doing anything with a trap representation
>>> invokes Undefined Behavior.
>>
>> You could allocate an array of eight void *s, malloc() a single byte**
>> of memory for each, and compare to that. Each pointer is guaranteed to
>> be unique, different from all other valid objects; each pointer is
>> guaranteed not to be valid (but do remember to check for null returns
>> from malloc(), uproariously unlikely as they may be in this case); and
>> crucially, being void *s and returns from malloc(), each is guaranteed
>> to be maximally aligned.
>>
>> _Or_ you could be sensible and not abuse different pointer values as
>> error indicators.
>
>OK. But then it should be OK to allocate
>
>void *pointers[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
>
>And do
>
>void *pointer = some_function();
>if (pointer >= &pointers && pointer <= &pointers+8) {
> Some code here
>}
>
>Right?
Ignoring the bugs...
No. As I pointed out in my other post, you cannot do relational
comparisons on pointers unless the two pointers point to the same
object. If you don't know that they point to the same object, you can
only test for (in)equality. The following would work:
if (ptr == pointers+0 ||
ptr == pointers+1 ||
ptr == pointers+2 ||
ptr == pointers+3 ||
ptr == pointers+4 ||
ptr == pointers+5 ||
ptr == pointers+6 ||
ptr == pointers+7)
Some code here
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-10-30 11:00 +0000 |
| Message-ID | <87d1vwfwnr.fsf@bsb.me.uk> |
| In reply to | #74228 |
"Morten W. Petersen" <morphex@gmail.com> writes:
> On 29.10.2015 22:45, Richard Bos wrote:
<snip>
>> You could allocate an array of eight void *s, malloc() a single byte**
>> of memory for each, and compare to that. Each pointer is guaranteed to
>> be unique, different from all other valid objects; each pointer is
>> guaranteed not to be valid (but do remember to check for null returns
>> from malloc(), uproariously unlikely as they may be in this case); and
>> crucially, being void *s and returns from malloc(), each is guaranteed
>> to be maximally aligned.
>>
>> _Or_ you could be sensible and not abuse different pointer values as
>> error indicators.
>
> OK. But then it should be OK to allocate
>
> void *pointers[8] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
>
> And do
>
> void *pointer = some_function();
> if (pointer >= &pointers && pointer <= &pointers+8) {
> Some code here
> }
>
> Right?
No, the types are wrong. There are various ways to do this but more
people are reluctant to put the effort in to writing it out as working
code because they don't think it's a good idea.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2015-10-29 23:48 -0500 |
| Message-ID | <46t53b5nqbf6dr81i66cemgup70kclk7qf@4ax.com> |
| In reply to | #74180 |
On Thu, 29 Oct 2015 16:59:31 +0100, "Morten W. Petersen"
<morphex@gmail.com> wrote:
>On 21.10.2015 20:15, James Kuyper wrote:
>> On 10/21/2015 01:45 PM, John Temples wrote:
>> ...
>>> There are many 8- and 16-bit platforms that have linear memory
>>> starting at address 0. The compiler could place an object at address
>>> 7, so (void*)7 would be a valid pointer to an object. You would have
>>> to reserve the memory at addresses 1-7 to prevent that from happening.
>>
>> The normal way you reserve space in C is to declare a named object to
>> occupy that space. C doesn't have the option of specifying the location
>> for an object, but you don't really need to. It doesn't really matter
>> whether its at address 7 or not - just use &overflow_error, rather than
>> (void*)7.
>
>Now you're talking about defining a variable and checking that address,
>right?
>
> From what I've gathered in this entire thread, it isn't possible to use
>the addresses 1-7 safely to indicate an error.
>
>However, I could declare an array of 8 char for example, and check
>the return value against addresses in that range.
A problem with that is that it's not possible to check for "any"
error, other than by checking all seven possible pointers individually
(plus, presumably, NULL).
IOW, you can't do:
char errors[7];
...
ptr = somefunc();
if (ptr >= (errors+0) && ptr <= (errors+6))
handle_errror_1_6();
To see if it matches any of those. If you don't know that the
pointers are to the same object, (in)equality is the only thing you
can portably test.
Basically, don't do that.
[toc] | [prev] | [next] | [standalone]
| From | "Morten W. Petersen" <morphex@gmail.com> |
|---|---|
| Date | 2015-10-30 11:05 +0100 |
| Message-ID | <n0vfdg$eks$1@speranza.aioe.org> |
| In reply to | #74224 |
On 30.10.2015 05:48, Robert Wessel wrote: [...] > IOW, you can't do: > > char errors[7]; > ... > ptr = somefunc(); > if (ptr >= (errors+0) && ptr <= (errors+6)) > handle_errror_1_6(); > > To see if it matches any of those. If you don't know that the > pointers are to the same object, (in)equality is the only thing you > can portably test. > > Basically, don't do that. OK. And what does portable mean here? What are the examples of allocating a small array where each member of that array do not have a sequential ascending or descending address? -Morten
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2015-10-30 07:45 -0400 |
| Message-ID | <kLIYx.1076$UN.250@fx28.iad> |
| In reply to | #74260 |
On 10/30/15 6:05 AM, Morten W. Petersen wrote: > On 30.10.2015 05:48, Robert Wessel wrote: > [...] >> IOW, you can't do: >> >> char errors[7]; >> ... >> ptr = somefunc(); >> if (ptr >= (errors+0) && ptr <= (errors+6)) >> handle_errror_1_6(); >> >> To see if it matches any of those. If you don't know that the >> pointers are to the same object, (in)equality is the only thing you >> can portably test. >> >> Basically, don't do that. > > OK. And what does portable mean here? What are the examples of > allocating a small array where each member of that array do not have a > sequential ascending or descending address? > > -Morten > The issue is that the standard only allows the use of relational comparisons (like < ) between pointers that are part of the same object (like an array). The practical effect of this is that there are some machines/implementations where you can get false positives, the most notable case is for a machine with segmented pointers where < may only check the offset, and not for the segments to match.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-10-30 05:04 -0700 |
| Message-ID | <e76ed551-babb-49ec-8bb8-6213dcbe4474@googlegroups.com> |
| In reply to | #74273 |
On Friday, October 30, 2015 at 11:45:34 AM UTC, Richard Damon wrote: > On 10/30/15 6:05 AM, Morten W. Petersen wrote: > > The issue is that the standard only allows the use of relational > comparisons (like < ) between pointers that are part of the same object > (like an array). > > The practical effect of this is that there are some > machines/implementations where you can get false positives, the most > notable case is for a machine with segmented pointers where < may only > check the offset, and not for the segments to match. > it's a nuisance, because you can't test if ptr is in array a without iterating through a testing every value for equality. A function ptr_in_range(void *ptr, void *start, void *end) would be handy.
[toc] | [prev] | [next] | [standalone]
| From | "Morten W. Petersen" <morphex@gmail.com> |
|---|---|
| Date | 2015-10-30 16:09 +0100 |
| Message-ID | <n1016b$mur$1@speranza.aioe.org> |
| In reply to | #74276 |
On 30.10.2015 13:04, Malcolm McLean wrote: > On Friday, October 30, 2015 at 11:45:34 AM UTC, Richard Damon wrote: >> On 10/30/15 6:05 AM, Morten W. Petersen wrote: >> >> The issue is that the standard only allows the use of relational >> comparisons (like < ) between pointers that are part of the same object >> (like an array). >> >> The practical effect of this is that there are some >> machines/implementations where you can get false positives, the most >> notable case is for a machine with segmented pointers where < may only >> check the offset, and not for the segments to match. >> > it's a nuisance, because you can't test if ptr is in array a without iterating > through a testing every value for equality. > A function ptr_in_range(void *ptr, void *start, void *end) > would be handy. Well, such a function would abstract away the logic so that a define, maybe set by some automated test, would choose the right approach. I've read a bit, and found that a pointer has at least an address and a type, in the parsing/compilation part. It could also contain other bits.. It also looks like x86 and ARM have a flat memory model, which means that the pointer in most cases is a simple non-negative number. So maybe have a compile-time test that checks the architecture and makes #define statements based on that? -Morten
[toc] | [prev] | [next] | [standalone]
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web