Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #13412 > unrolled thread
| Started by | tim <nospam@nospam.com> |
|---|---|
| First post | 2011-11-15 19:59 +0000 |
| Last post | 2012-01-26 08:48 -0800 |
| Articles | 20 on this page of 50 — 21 participants |
Back to article view | Back to comp.lang.c
when is typecasting (unsigned char*) to (char*) dangerous? tim <nospam@nospam.com> - 2011-11-15 19:59 +0000
Re: when is typecasting (unsigned char*) to (char*) dangerous? Kaz Kylheku <kaz@kylheku.com> - 2011-11-15 20:51 +0000
Re: when is typecasting (unsigned char*) to (char*) dangerous? tim <nospam@nospam.com> - 2011-11-16 16:55 +0000
Re: when is typecasting (unsigned char*) to (char*) dangerous? Kaz Kylheku <kaz@kylheku.com> - 2011-11-16 17:54 +0000
Re: when is typecasting (unsigned char*) to (char*) dangerous? Keith Thompson <kst-u@mib.org> - 2011-11-16 11:27 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Kaz Kylheku <kaz@kylheku.com> - 2011-11-16 19:49 +0000
Re: when is typecasting (unsigned char*) to (char*) dangerous? Keith Thompson <kst-u@mib.org> - 2011-11-16 11:52 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Kaz Kylheku <kaz@kylheku.com> - 2011-11-16 20:06 +0000
Re: when is typecasting (unsigned char*) to (char*) dangerous? Keith Thompson <kst-u@mib.org> - 2011-11-16 14:55 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 04:42 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? James Kuyper <jameskuyper@verizon.net> - 2011-11-16 15:15 -0500
Re: when is typecasting (unsigned char*) to (char*) dangerous? James Kuyper <jameskuyper@verizon.net> - 2011-11-16 15:24 -0500
Re: when is typecasting (unsigned char*) to (char*) dangerous? Harald van Dijk <truedfx@gmail.com> - 2011-11-16 12:41 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? James Kuyper <jameskuyper@verizon.net> - 2011-11-16 16:02 -0500
Re: when is typecasting (unsigned char*) to (char*) dangerous? Harald van Dijk <truedfx@gmail.com> - 2011-11-16 13:23 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Keith Thompson <kst-u@mib.org> - 2011-11-16 15:32 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Harald van Dijk <truedfx@gmail.com> - 2011-11-16 17:02 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? pete <pfiland@mindspring.com> - 2011-11-16 21:38 -0500
Re: when is typecasting (unsigned char*) to (char*) dangerous? Keith Thompson <kst-u@mib.org> - 2011-11-16 19:22 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Harald van Dijk <truedfx@gmail.com> - 2011-11-16 23:08 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Keith Thompson <kst-u@mib.org> - 2011-11-16 23:46 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Harald van Dijk <truedfx@gmail.com> - 2011-11-17 09:15 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-25 04:54 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Vincenzo Mercuri <vincenzo.mercuri@yahoo.it> - 2011-11-16 21:44 +0100
Re: when is typecasting (unsigned char*) to (char*) dangerous? Kenneth Brody <kenbrody@spamcop.net> - 2011-11-16 13:17 -0500
Re: when is typecasting (unsigned char*) to (char*) dangerous? Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-11-16 00:58 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-11-16 01:36 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Markus Wichmann <nullplan@gmx.net> - 2011-11-16 13:28 +0100
Re: when is typecasting (unsigned char*) to (char*) dangerous? nroberts <roberts.noah@gmail.com> - 2011-11-16 08:14 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? BGB <cr88192@hotmail.com> - 2011-11-16 12:03 -0700
Re: when is typecasting (unsigned char*) to (char*) dangerous? blp@cs.stanford.edu (Ben Pfaff) - 2011-11-16 08:58 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Vincenzo Mercuri <vincenzo.mercuri@yahoo.it> - 2011-11-16 19:04 +0100
Re: when is typecasting (unsigned char*) to (char*) dangerous? Ben Pfaff <blp@cs.stanford.edu> - 2011-11-16 10:05 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Keith Thompson <kst-u@mib.org> - 2011-11-16 11:19 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Vincenzo Mercuri <vincenzo.mercuri@yahoo.it> - 2011-11-16 20:58 +0100
Re: when is typecasting (unsigned char*) to (char*) dangerous? Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-11-18 15:37 +0200
Re: when is typecasting (unsigned char*) to (char*) dangerous? Vincenzo Mercuri <vincenzo.mercuri@yahoo.it> - 2011-11-18 19:41 +0100
Re: when is typecasting (unsigned char*) to (char*) dangerous? Vincenzo Mercuri <vincenzo.mercuri@yahoo.it> - 2011-11-18 19:43 +0100
Re: when is typecasting (unsigned char*) to (char*) dangerous? Lauri Alanko <la@iki.fi> - 2011-11-17 19:09 +0000
Re: when is typecasting (unsigned char*) to (char*) dangerous? Harald van Dijk <truedfx@gmail.com> - 2011-11-17 11:44 -0800
Re: when is typecasting (unsigned char*) to (char*) dangerous? Keith Thompson <kst-u@mib.org> - 2011-11-17 13:16 -0800
Re: when is casting (unsigned char*) to (signed char*) dangerous? Shao Miller <sha0.miller@gmail.com> - 2012-01-22 02:22 -0500
Re: when is casting (unsigned char*) to (signed char*) dangerous? Harald van Dijk <haraldvdijk@gmail.com> - 2012-01-22 12:14 -0800
Re: when is casting (unsigned char*) to (signed char*) dangerous? Keith Thompson <kst-u@mib.org> - 2012-01-23 00:37 -0800
Re: when is casting (unsigned char*) to (signed char*) dangerous? Jens Gustedt <jens.gustedt@loria.fr> - 2012-01-24 15:10 +0100
Re: when is casting (unsigned char*) to (signed char*) dangerous? Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-26 08:55 -0800
Re: when is casting (unsigned char*) to (signed char*) dangerous? Keith Thompson <kst-u@mib.org> - 2012-01-26 11:32 -0800
Re: when is casting (unsigned char*) to (signed char*) dangerous? Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-31 21:57 -0800
Re: when is casting (unsigned char*) to (signed char*) dangerous? Shao Miller <sha0.miller@gmail.com> - 2012-02-01 01:12 -0500
Re: when is casting (unsigned char*) to (signed char*) dangerous? Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-26 08:48 -0800
Page 1 of 3 [1] 2 3 Next page →
| From | tim <nospam@nospam.com> |
|---|---|
| Date | 2011-11-15 19:59 +0000 |
| Subject | when is typecasting (unsigned char*) to (char*) dangerous? |
| Message-ID | <j9ugaj$q30$4@speranza.aioe.org> |
thanks in advance for your help, tim
[toc] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2011-11-15 20:51 +0000 |
| Message-ID | <20111115125004.175@kylheku.com> |
| In reply to | #13412 |
On 2011-11-15, tim <nospam@nospam.com> wrote: > thanks in advance for your help, tim It's dangerous when it's done by someone who got other people to answer his technical interview or homework questions.
[toc] | [prev] | [next] | [standalone]
| From | tim <nospam@nospam.com> |
|---|---|
| Date | 2011-11-16 16:55 +0000 |
| Message-ID | <ja0pub$bb4$1@speranza.aioe.org> |
| In reply to | #13418 |
THIS IS NOT A HOMEWORK On Tue, 15 Nov 2011 20:51:01 +0000, Kaz Kylheku wrote: > On 2011-11-15, tim <nospam@nospam.com> wrote: >> thanks in advance for your help, tim > > It's dangerous when it's done by someone who got other people to answer > his technical interview or homework questions.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2011-11-16 17:54 +0000 |
| Message-ID | <20111116094733.821@kylheku.com> |
| In reply to | #13487 |
On 2011-11-16, tim <nospam@nospam.com> wrote: > THIS IS NOT A HOMEWORK In that case, ... If the unsigned char * value is already well defined and everything, it is safe to convert it to char *, and even to access the memory. In C, this is not considered to be invalid aliasing. Any object can be accessed as an array of characters, plain, signed or unsigned. Sometimes this conversion will be necessary. If you know that some region of memory contains a null terminate C string that you would like to compare with strcmp, you will end up doing that cast. One thing that may be dangerous is that char may be a signed value. This means that through a char * pointer, some of the byte values will appear negative. You can trip up like this: int translated_char = table[*char_ptr]; /* oops, negative index */ Accessing memory using an unsigned char * pointer ensures that bytes are treated as positive binary numbers.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-11-16 11:27 -0800 |
| Message-ID | <lnd3crzx48.fsf@nuthaus.mib.org> |
| In reply to | #13490 |
Kaz Kylheku <kaz@kylheku.com> writes:
> On 2011-11-16, tim <nospam@nospam.com> wrote:
>> THIS IS NOT A HOMEWORK
(no need to shout)
> In that case, ...
>
> If the unsigned char * value is already well defined and everything, it is
> safe to convert it to char *, and even to access the memory. In C, this
> is not considered to be invalid aliasing. Any object can be accessed
> as an array of characters, plain, signed or unsigned.
Does the standard guarantee that? I was unable to find anything
that permits treating arbitrary objects as arrays of anything other
than unsigned char.
C99 6.1.6.1p4:
Values stored in non-bit-field objects of any other object type
consist of n * CHAR_BIT bits, where n is the size of an object
of that type, in bytes. The value may be copied into an object
of type unsigned char [n] (e.g., by memcpy); the resulting set
of bytes is called the *object representation& of the value.
C99 6.2.6.2p1:
For unsigned integer types other than unsigned char, the bits of the
object representation shall be divided into two groups: value bits
and padding bits (there need not be any of the latter).
p2:
Which of these [sign and magnitude, two's complement, ones'
complement] applies is implementation-defined, as is whether
the value with sign bit 1 and all value bits zero (for the
first two), or with sign bit and all value bits 1 (for ones’
complement), is a trap representation or a normal value.
As far as I can tell, given that CHAR_BIT==8, it would be legal for an
implementation to have plain char (if it's signed) and signed char have
a range of -127 .. +127, with the extra representation being a trap
representation. It would even be legal for signed char to have padding
bits, possibly leading to even more trap representation; given the
requirements for SCHAR_MIN and SCHAR_MAX, that's possible only if
CHAR_BIT > 8.
I seriously doubt that any real-world implementation takes advantage
of this.
I have a vague memory of a statement that plain and signed char cannot
have trap representations, but I can't confirm that from the standard.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2011-11-16 19:49 +0000 |
| Message-ID | <20111116113023.119@kylheku.com> |
| In reply to | #13503 |
On 2011-11-16, Keith Thompson <kst-u@mib.org> wrote: > Kaz Kylheku <kaz@kylheku.com> writes: >> On 2011-11-16, tim <nospam@nospam.com> wrote: >>> THIS IS NOT A HOMEWORK > > (no need to shout) > >> In that case, ... >> >> If the unsigned char * value is already well defined and everything, it is >> safe to convert it to char *, and even to access the memory. In C, this >> is not considered to be invalid aliasing. Any object can be accessed >> as an array of characters, plain, signed or unsigned. > > Does the standard guarantee that? Even if there is a trap representation there, it's not an aliasing issue. If you could not alias an object using chars, then no access at all would be well-defined.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-11-16 11:52 -0800 |
| Message-ID | <ln4ny3zvxv.fsf@nuthaus.mib.org> |
| In reply to | #13505 |
Kaz Kylheku <kaz@kylheku.com> writes:
> On 2011-11-16, Keith Thompson <kst-u@mib.org> wrote:
>> Kaz Kylheku <kaz@kylheku.com> writes:
>>> On 2011-11-16, tim <nospam@nospam.com> wrote:
>>>> THIS IS NOT A HOMEWORK
>>
>> (no need to shout)
>>
>>> In that case, ...
>>>
>>> If the unsigned char * value is already well defined and everything, it is
>>> safe to convert it to char *, and even to access the memory. In C, this
>>> is not considered to be invalid aliasing. Any object can be accessed
>>> as an array of characters, plain, signed or unsigned.
>>
>> Does the standard guarantee that?
>
> Even if there is a trap representation there, it's not an aliasing issue.
>
> If you could not alias an object using chars, then no access at all would
> be well-defined.
I don't follow your reasoning.
Where does the standard say that you can alias any object with an
array of plain or signed char?
If you can't do so, how does that affect the ability to access an
object as its declared type, or as an array of unsigned char?
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2011-11-16 20:06 +0000 |
| Message-ID | <20111116120259.793@kylheku.com> |
| In reply to | #13507 |
On 2011-11-16, Keith Thompson <kst-u@mib.org> wrote: > Kaz Kylheku <kaz@kylheku.com> writes: >> On 2011-11-16, Keith Thompson <kst-u@mib.org> wrote: >>> Kaz Kylheku <kaz@kylheku.com> writes: >>>> On 2011-11-16, tim <nospam@nospam.com> wrote: >>>>> THIS IS NOT A HOMEWORK >>> >>> (no need to shout) >>> >>>> In that case, ... >>>> >>>> If the unsigned char * value is already well defined and everything, it is >>>> safe to convert it to char *, and even to access the memory. In C, this >>>> is not considered to be invalid aliasing. Any object can be accessed >>>> as an array of characters, plain, signed or unsigned. >>> >>> Does the standard guarantee that? >> >> Even if there is a trap representation there, it's not an aliasing issue. >> >> If you could not alias an object using chars, then no access at all would >> be well-defined. > > I don't follow your reasoning. > > Where does the standard say that you can alias any object with an > array of plain or signed char? 6.5 paragraph 7. An object can be accessed with an lvalue which is of character type.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-11-16 14:55 -0800 |
| Message-ID | <lnzkfvy8wd.fsf@nuthaus.mib.org> |
| In reply to | #13511 |
Kaz Kylheku <kaz@kylheku.com> writes:
> On 2011-11-16, Keith Thompson <kst-u@mib.org> wrote:
>> Kaz Kylheku <kaz@kylheku.com> writes:
>>> On 2011-11-16, Keith Thompson <kst-u@mib.org> wrote:
>>>> Kaz Kylheku <kaz@kylheku.com> writes:
>>>>> On 2011-11-16, tim <nospam@nospam.com> wrote:
>>>>>> THIS IS NOT A HOMEWORK
>>>>
>>>> (no need to shout)
>>>>
>>>>> In that case, ...
>>>>>
>>>>> If the unsigned char * value is already well defined and
>>>>> everything, it is safe to convert it to char *, and even to
>>>>> access the memory. In C, this is not considered to be invalid
>>>>> aliasing. Any object can be accessed as an array of characters,
>>>>> plain, signed or unsigned.
>>>>
>>>> Does the standard guarantee that?
>>>
>>> Even if there is a trap representation there, it's not an aliasing issue.
>>>
>>> If you could not alias an object using chars, then no access at all would
>>> be well-defined.
>>
>> I don't follow your reasoning.
And I still don't. If, hypothetically, the standard permitted objects
to be aliased using unsigned chars but not signed or plain chars, how
would that imply that "no access at all would be well-defined"?
>> Where does the standard say that you can alias any object with an
>> array of plain or signed char?
>
> 6.5 paragraph 7. An object can be accessed with an lvalue which
> is of character type.
Ah, thank you, that's one of the clues I was missing. The other is
6.2.6.1p5 (thanks to James Kuyper for catching that one); that says
explicitly that you can access an object via an lvalue of character
type.
So let's assume that you have an object of type unsigned char with
the value SCHAR_MAX + 1, and you access it as a signed char --
but that representation is a trap representation
for signed char:
unsigned char u = SCHAR_MAX + 1;
signed char s = *(signed char*)&u;
My reading is that the behavior is undefined by omission. 6.2.6.1p5
says that storing a non-character trap representation has undefined
behavior; it explicitly excludes character types. 6.5p7 says that
an object shall have its stored value accessed *only* by an lvalue of
certain types, including character types, but that doesn't imply that
the behavior of such an access is defined. For example, accessing
an int object by an lvalue of of type int is permitted by 6.5p7,
but has undefined behavior if the object holds a trap representation.
If the behavior is defined, what is it?
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-01-25 04:42 -0800 |
| Message-ID | <kfn8vkw9cnd.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #13526 |
Keith Thompson <kst-u@mib.org> writes: > Kaz Kylheku <kaz@kylheku.com> writes: >> On 2011-11-16, Keith Thompson <kst-u@mib.org> wrote: >>> Kaz Kylheku <kaz@kylheku.com> writes: >>>> On 2011-11-16, Keith Thompson <kst-u@mib.org> wrote: >>>>> Kaz Kylheku <kaz@kylheku.com> writes: >>>>>> On 2011-11-16, tim <nospam@nospam.com> wrote: >>>>>>> THIS IS NOT A HOMEWORK >>>>> >>>>> (no need to shout) >>>>> >>>>>> In that case, ... >>>>>> >>>>>> If the unsigned char * value is already well defined and >>>>>> everything, it is safe to convert it to char *, and even to >>>>>> access the memory. In C, this is not considered to be invalid >>>>>> aliasing. Any object can be accessed as an array of characters, >>>>>> plain, signed or unsigned. >>>>> >>>>> Does the standard guarantee that? >>>> >>>> Even if there is a trap representation there, it's not an aliasing issue. >>>> >>>> If you could not alias an object using chars, then no access at all would >>>> be well-defined. >>> >>> I don't follow your reasoning. > > And I still don't. If, hypothetically, the standard permitted objects > to be aliased using unsigned chars but not signed or plain chars, how > would that imply that "no access at all would be well-defined"? > >>> Where does the standard say that you can alias any object with an >>> array of plain or signed char? >> >> 6.5 paragraph 7. An object can be accessed with an lvalue which >> is of character type. > > Ah, thank you, that's one of the clues I was missing. The other is > 6.2.6.1p5 (thanks to James Kuyper for catching that one); that says > explicitly that you can access an object via an lvalue of character > type. Neither 6.5 p7 nor 6.2.6.1 p5 promises that access using a character type must be defined behavior. What they do say is that access using (many) other types is _un_defined behavior. Simply failing to disallow something doesn't mean it's defined; there also must be provided some definition that works under the circumstances in question. > So let's assume that you have an object of type unsigned char with > the value SCHAR_MAX + 1, and you access it as a signed char -- > but that representation is a trap representation > for signed char: > > unsigned char u = SCHAR_MAX + 1; > signed char s = *(signed char*)&u; > > My reading is that the behavior is undefined by omission. 6.2.6.1p5 > says that storing a non-character trap representation has undefined > behavior; it explicitly excludes character types. 6.5p7 says that > an object shall have its stored value accessed *only* by an lvalue of > certain types, including character types, but that doesn't imply that > the behavior of such an access is defined. For example, accessing > an int object by an lvalue of of type int is permitted by 6.5p7, > but has undefined behavior if the object holds a trap representation. > > If the behavior is defined, what is it? Assuming that the object representation in 'u' is a trap representation for signed char, the behavior is undefined. This conclusion follows directly from 6.5 p5 and the definition of trap representation (and 6.3.2.1 p2, naturally).
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-11-16 15:15 -0500 |
| Message-ID | <4EC419F7.8030207@verizon.net> |
| In reply to | #13507 |
On 11/16/2011 02:52 PM, Keith Thompson wrote: ... > Where does the standard say that you can alias any object with an > array of plain or signed char? 6.5p7, last item: "a character type". The term "alias" is used only in footnote 76, but that's sufficient for this purpose.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-11-16 15:24 -0500 |
| Message-ID | <4EC41C0B.2040304@verizon.net> |
| In reply to | #13503 |
On 11/16/2011 02:27 PM, Keith Thompson wrote: ... > I have a vague memory of a statement that plain and signed char cannot > have trap representations, but I can't confirm that from the standard. I know of no reason why signed char (and therefore, char) cannot have trap representations. However, every statement in 6.2.6.1p5 which says that the behavior is undefined when a trap representation is involved, explicitly excludes all character types, not just unsigned char. I'm not quite sure what to make of that fact, but I'm sure that explicitly excluding all character types was intentional; I'm not so sure whether it was intentional to allow signed char to have trap representations.
[toc] | [prev] | [next] | [standalone]
| From | Harald van Dijk <truedfx@gmail.com> |
|---|---|
| Date | 2011-11-16 12:41 -0800 |
| Message-ID | <d784672e-5bb7-44d0-b8af-a141aead4cda@a5g2000vbb.googlegroups.com> |
| In reply to | #13516 |
On Nov 16, 9:24 pm, James Kuyper <jameskuy...@verizon.net> wrote: > On 11/16/2011 02:27 PM, Keith Thompson wrote: > ... > > > I have a vague memory of a statement that plain and signed char cannot > > have trap representations, but I can't confirm that from the standard. > > I know of no reason why signed char (and therefore, char) cannot have > trap representations. However, every statement in 6.2.6.1p5 which says > that the behavior is undefined when a trap representation is involved, > explicitly excludes all character types, not just unsigned char. I'm not > quite sure what to make of that fact, but I'm sure that explicitly > excluding all character types was intentional; I'm not so sure whether > it was intentional to allow signed char to have trap representations. 6.2.6.1p5 refers to the trap representations for the type of the object. In other words, if an object p of type void * holds a trap representation, 6.2.6.1p5 makes it explicit that reading that object as void * is not valid. It doesn't say that signed char can be used to access the bytes in p, it merely doesn't say that it can't. If signed char has no trap representations, the required behaviour can be inferred from other parts of the standard. If signed char does have trap representations, then even though 6.2.6.1p5 doesn't explicitly state that the behaviour is undefined, since the standard never defines the behaviour, the end result is the same.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-11-16 16:02 -0500 |
| Message-ID | <4EC424E0.8060506@verizon.net> |
| In reply to | #13519 |
On 11/16/2011 03:41 PM, Harald van Dijk wrote: > On Nov 16, 9:24 pm, James Kuyper <jameskuy...@verizon.net> wrote: ... >> I know of no reason why signed char (and therefore, char) cannot have >> trap representations. However, every statement in 6.2.6.1p5 which says >> that the behavior is undefined when a trap representation is involved, >> explicitly excludes all character types, not just unsigned char. I'm not >> quite sure what to make of that fact, but I'm sure that explicitly >> excluding all character types was intentional; I'm not so sure whether >> it was intentional to allow signed char to have trap representations. > > 6.2.6.1p5 refers to the trap representations for the type of the > object. In other words, if an object p of type void * holds a trap > representation, 6.2.6.1p5 makes it explicit that reading that object > as void * is not valid. So, in your opinion, what is the significance of the exclusion of character types from those statements? What do those statements mean, with those exclusions, that differs from what they would mean if those exclusions were dropped? Please accompany your explanation with specific examples of code that would have defined behavior under the existing rules, but not with that modification, or vice-versa.
[toc] | [prev] | [next] | [standalone]
| From | Harald van Dijk <truedfx@gmail.com> |
|---|---|
| Date | 2011-11-16 13:23 -0800 |
| Message-ID | <c4cf3125-f590-4122-80ee-7e6c187d0963@f29g2000yqa.googlegroups.com> |
| In reply to | #13520 |
On Nov 16, 10:02 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> On 11/16/2011 03:41 PM, Harald van Dijk wrote:
> > On Nov 16, 9:24 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> ...
> >> I know of no reason why signed char (and therefore, char) cannot have
> >> trap representations. However, every statement in 6.2.6.1p5 which says
> >> that the behavior is undefined when a trap representation is involved,
> >> explicitly excludes all character types, not just unsigned char. I'm not
> >> quite sure what to make of that fact, but I'm sure that explicitly
> >> excluding all character types was intentional; I'm not so sure whether
> >> it was intentional to allow signed char to have trap representations.
>
> > 6.2.6.1p5 refers to the trap representations for the type of the
> > object. In other words, if an object p of type void * holds a trap
> > representation, 6.2.6.1p5 makes it explicit that reading that object
> > as void * is not valid.
>
> So, in your opinion, what is the significance of the exclusion of
> character types from those statements? What do those statements mean,
> with those exclusions, that differs from what they would mean if those
> exclusions were dropped? Please accompany your explanation with specific
> examples of code that would have defined behavior under the existing
> rules, but not with that modification, or vice-versa.
If those exclusions were dropped, then using memcpy (or rather, a
custom function written in standard C that behaves exactly like
memcpy) to copy an object holding a trap representation would be
invalid.
/* the standard function memcpy, but implemented in 100% standard C */
extern void *mymemcpy(void *dest, void *src, size_t n);
struct S
{
int ptrIsValid;
void *ptr;
};
{
struct S s1, s2;
s2.ptrIsValid = 0; /* ptr is left uninitialised */
mymemcpy(&s1, &s2, sizeof(s1));
}
Without the exclusion in 6.2.6.1p5, if pointer types can have trap
representations, mymemcpy would potentially use a character type to
read a trap representation. This should be allowed, and by excluding
character types in that paragraph, this is allowed.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-11-16 15:32 -0800 |
| Message-ID | <lnvcqjy76h.fsf@nuthaus.mib.org> |
| In reply to | #13522 |
Harald van Dijk <truedfx@gmail.com> writes:
> On Nov 16, 10:02 pm, James Kuyper <jameskuy...@verizon.net> wrote:
>> On 11/16/2011 03:41 PM, Harald van Dijk wrote:
>> > On Nov 16, 9:24 pm, James Kuyper <jameskuy...@verizon.net> wrote:
>> ...
>> >> I know of no reason why signed char (and therefore, char) cannot have
>> >> trap representations. However, every statement in 6.2.6.1p5 which says
>> >> that the behavior is undefined when a trap representation is involved,
>> >> explicitly excludes all character types, not just unsigned char. I'm not
>> >> quite sure what to make of that fact, but I'm sure that explicitly
>> >> excluding all character types was intentional; I'm not so sure whether
>> >> it was intentional to allow signed char to have trap representations.
>>
>> > 6.2.6.1p5 refers to the trap representations for the type of the
>> > object. In other words, if an object p of type void * holds a trap
>> > representation, 6.2.6.1p5 makes it explicit that reading that object
>> > as void * is not valid.
>>
>> So, in your opinion, what is the significance of the exclusion of
>> character types from those statements? What do those statements mean,
>> with those exclusions, that differs from what they would mean if those
>> exclusions were dropped? Please accompany your explanation with specific
>> examples of code that would have defined behavior under the existing
>> rules, but not with that modification, or vice-versa.
>
> If those exclusions were dropped, then using memcpy (or rather, a
> custom function written in standard C that behaves exactly like
> memcpy) to copy an object holding a trap representation would be
> invalid.
>
> /* the standard function memcpy, but implemented in 100% standard C */
> extern void *mymemcpy(void *dest, void *src, size_t n);
>
> struct S
> {
> int ptrIsValid;
> void *ptr;
> };
>
> {
> struct S s1, s2;
> s2.ptrIsValid = 0; /* ptr is left uninitialised */
> mymemcpy(&s1, &s2, sizeof(s1));
> }
>
> Without the exclusion in 6.2.6.1p5, if pointer types can have trap
> representations, mymemcpy would potentially use a character type to
> read a trap representation. This should be allowed, and by excluding
> character types in that paragraph, this is allowed.
memcpy() can just use unsigned char, which is guaranteed not to have
padding bits or trap representations.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Harald van Dijk <truedfx@gmail.com> |
|---|---|
| Date | 2011-11-16 17:02 -0800 |
| Message-ID | <033963f6-0c48-48f2-8cc8-161360fc7b76@r28g2000yqj.googlegroups.com> |
| In reply to | #13528 |
On Nov 17, 12:32 am, Keith Thompson <ks...@mib.org> wrote:
> Harald van Dijk <true...@gmail.com> writes:
> > On Nov 16, 10:02 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> >> On 11/16/2011 03:41 PM, Harald van Dijk wrote:
> >> > On Nov 16, 9:24 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> >> ...
> >> >> I know of no reason why signed char (and therefore, char) cannot have
> >> >> trap representations. However, every statement in 6.2.6.1p5 which says
> >> >> that the behavior is undefined when a trap representation is involved,
> >> >> explicitly excludes all character types, not just unsigned char. I'm not
> >> >> quite sure what to make of that fact, but I'm sure that explicitly
> >> >> excluding all character types was intentional; I'm not so sure whether
> >> >> it was intentional to allow signed char to have trap representations.
>
> >> > 6.2.6.1p5 refers to the trap representations for the type of the
> >> > object. In other words, if an object p of type void * holds a trap
> >> > representation, 6.2.6.1p5 makes it explicit that reading that object
> >> > as void * is not valid.
>
> >> So, in your opinion, what is the significance of the exclusion of
> >> character types from those statements? What do those statements mean,
> >> with those exclusions, that differs from what they would mean if those
> >> exclusions were dropped? Please accompany your explanation with specific
> >> examples of code that would have defined behavior under the existing
> >> rules, but not with that modification, or vice-versa.
>
> > If those exclusions were dropped, then using memcpy (or rather, a
> > custom function written in standard C that behaves exactly like
> > memcpy) to copy an object holding a trap representation would be
> > invalid.
>
> > /* the standard function memcpy, but implemented in 100% standard C */
> > extern void *mymemcpy(void *dest, void *src, size_t n);
>
> > struct S
> > {
> > int ptrIsValid;
> > void *ptr;
> > };
>
> > {
> > struct S s1, s2;
> > s2.ptrIsValid = 0; /* ptr is left uninitialised */
> > mymemcpy(&s1, &s2, sizeof(s1));
> > }
>
> > Without the exclusion in 6.2.6.1p5, if pointer types can have trap
> > representations, mymemcpy would potentially use a character type to
> > read a trap representation. This should be allowed, and by excluding
> > character types in that paragraph, this is allowed.
>
> memcpy() can just use unsigned char, which is guaranteed not to have
> padding bits or trap representations.
Yes, but that was not the point I was trying to make. I'm reading
s2.ptr, which potentially holds a trap representation, and 6.2.6.1p5
disallows reading trap representations. It doesn't refer to
representations that do not represent a value in the type of the
lvalue expression, it refers to representations that do not represent
a value in the type of the object. The object has type void *, even if
it's accessed using unsigned char. That's why there needs to be a
specific exception for when the lvalue expression has character type.
[toc] | [prev] | [next] | [standalone]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2011-11-16 21:38 -0500 |
| Message-ID | <4EC4738D.6D21@mindspring.com> |
| In reply to | #13531 |
=?UTF-8?Q?Harald_van_D=C4=B3k?= wrote:
>
> On Nov 17, 12:32Â am, Keith Thompson <ks...@mib.org> wrote:
> > Harald van Dijk <true...@gmail.com> writes:
> > > On Nov 16, 10:02Â pm, James Kuyper <jameskuy...@verizon.net> wrote:
> > >> On 11/16/2011 03:41 PM, Harald van Dijk wrote:
> > >> > On Nov 16, 9:24 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> > >> ...
> > >> >> I know of no reason why signed char (and therefore, char) cannot have
> > >> >> trap representations. However, every statement in 6.2.6.1p5 which says
> > >> >> that the behavior is undefined when a trap representation is involved,
> > >> >> explicitly excludes all character types, not just unsigned char. I'm not
> > >> >> quite sure what to make of that fact, but I'm sure that explicitly
> > >> >> excluding all character types was intentional; I'm not so sure whether
> > >> >> it was intentional to allow signed char to have trap representations.
> >
> > >> > 6.2.6.1p5 refers to the trap representations for the type of the
> > >> > object. In other words, if an object p of type void * holds a trap
> > >> > representation, 6.2.6.1p5 makes it explicit that reading that object
> > >> > as void * is not valid.
> >
> > >> So, in your opinion, what is the significance of the exclusion of
> > >> character types from those statements? What do those statements mean,
> > >> with those exclusions, that differs from what they would mean if those
> > >> exclusions were dropped? Please accompany your explanation with specific
> > >> examples of code that would have defined behavior under the existing
> > >> rules, but not with that modification, or vice-versa.
> >
> > > If those exclusions were dropped, then using memcpy (or rather, a
> > > custom function written in standard C that behaves exactly like
> > > memcpy) to copy an object holding a trap representation would be
> > > invalid.
> >
> > > /* the standard function memcpy, but implemented in 100% standard C */
> > > extern void *mymemcpy(void *dest, void *src, size_t n);
> >
> > > struct S
> > > {
> > > Â int ptrIsValid;
> > > Â void *ptr;
> > > };
> >
> > > {
> > > Â struct S s1, s2;
> > > Â s2.ptrIsValid = 0; /* ptr is left uninitialised */
> > > Â mymemcpy(&s1, &s2, sizeof(s1));
> > > }
> >
> > > Without the exclusion in 6.2.6.1p5, if pointer types can have trap
> > > representations, mymemcpy would potentially use a character type to
> > > read a trap representation. This should be allowed, and by excluding
> > > character types in that paragraph, this is allowed.
> >
> > memcpy() can just use unsigned char, which is guaranteed not to have
> > padding bits or trap representations.
>
> Yes, but that was not the point I was trying to make. I'm reading
> s2.ptr, which potentially holds a trap representation, and 6.2.6.1p5
> disallows reading trap representations. It doesn't refer to
> representations that do not represent a value in the type of the
> lvalue expression, it refers to representations that do not represent
> a value in the type of the object. The object has type void *, even if
> it's accessed using unsigned char. That's why there needs to be a
> specific exception for when the lvalue expression has character type.
Pointers to character types have problems with
neither size
nor alignment
of the bytes that they point to.
--
pete
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-11-16 19:22 -0800 |
| Message-ID | <lnmxbvxwja.fsf@nuthaus.mib.org> |
| In reply to | #13531 |
Harald van Dijk <truedfx@gmail.com> writes:
[...]
> Yes, but that was not the point I was trying to make. I'm reading
> s2.ptr, which potentially holds a trap representation, and 6.2.6.1p5
> disallows reading trap representations. It doesn't refer to
> representations that do not represent a value in the type of the
> lvalue expression, it refers to representations that do not represent
> a value in the type of the object. The object has type void *, even if
> it's accessed using unsigned char. That's why there needs to be a
> specific exception for when the lvalue expression has character type.
That's an interesting interpretation, but I'm still not quite convinced.
Here's the paragraph:
Certain object representations need not represent a value of
the object type. If the stored value of an object has such a
representation and is read by an lvalue expression that does
not have character type, the behavior is undefined. If such
a representation is produced by a side effect that modifies
all or any part of the object by an lvalue expression that
does not have character type, the behavior is undefined.
Such a representation is called a *trap representation*.
I still think that it refers to (or *should* refer to) a trap
representation for the type of the lvalue.
Consider:
void *ptr = malloc(sizeof (int));
assert(ptr != NULL);
/* code to set the bytes pointed to by ptr to a
trap representation for type int */
int n = *(int*)ptr;
The object created by the malloc() call isn't an object of type int;
it's just raw storage. If 6.2.6.1p5 doesn't imply that accessing
it via an lvalue of type int has undefined behavior, then what does?
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Harald van Dijk <truedfx@gmail.com> |
|---|---|
| Date | 2011-11-16 23:08 -0800 |
| Message-ID | <3c074538-5dd2-4f17-b1e9-6654851ae5f2@o14g2000yqh.googlegroups.com> |
| In reply to | #13542 |
On Nov 17, 4:22 am, Keith Thompson <ks...@mib.org> wrote: > Here's the paragraph: > > Certain object representations need not represent a value of > the object type. If the stored value of an object has such a > representation and is read by an lvalue expression that does > not have character type, the behavior is undefined. If such > a representation is produced by a side effect that modifies > all or any part of the object by an lvalue expression that > does not have character type, the behavior is undefined. > Such a representation is called a *trap representation*. > > I still think that it refers to (or *should* refer to) a trap > representation for the type of the lvalue. > > Consider: > > void *ptr = malloc(sizeof (int)); > assert(ptr != NULL); > /* code to set the bytes pointed to by ptr to a > trap representation for type int */ > int n = *(int*)ptr; > > The object created by the malloc() call isn't an object of type int; > it's just raw storage. If 6.2.6.1p5 doesn't imply that accessing > it via an lvalue of type int has undefined behavior, then what does? If *ptr doesn't hold an int, then reading it as an int is a violation of the aliasing rules.
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web