Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #13412 > unrolled thread

when is typecasting (unsigned char*) to (char*) dangerous?

Started bytim <nospam@nospam.com>
First post2011-11-15 19:59 +0000
Last post2012-01-26 08:48 -0800
Articles 20 on this page of 50 — 21 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#13412 — when is typecasting (unsigned char*) to (char*) dangerous?

Fromtim <nospam@nospam.com>
Date2011-11-15 19:59 +0000
Subjectwhen 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]


#13418

FromKaz Kylheku <kaz@kylheku.com>
Date2011-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]


#13487

Fromtim <nospam@nospam.com>
Date2011-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]


#13490

FromKaz Kylheku <kaz@kylheku.com>
Date2011-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]


#13503

FromKeith Thompson <kst-u@mib.org>
Date2011-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]


#13505

FromKaz Kylheku <kaz@kylheku.com>
Date2011-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]


#13507

FromKeith Thompson <kst-u@mib.org>
Date2011-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]


#13511

FromKaz Kylheku <kaz@kylheku.com>
Date2011-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]


#13526

FromKeith Thompson <kst-u@mib.org>
Date2011-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]


#16188

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-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]


#13512

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-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]


#13516

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-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]


#13519

FromHarald van Dijk <truedfx@gmail.com>
Date2011-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]


#13520

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-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]


#13522

FromHarald van Dijk <truedfx@gmail.com>
Date2011-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]


#13528

FromKeith Thompson <kst-u@mib.org>
Date2011-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]


#13531

FromHarald van Dijk <truedfx@gmail.com>
Date2011-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]


#13536

Frompete <pfiland@mindspring.com>
Date2011-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]


#13542

FromKeith Thompson <kst-u@mib.org>
Date2011-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]


#13546

FromHarald van Dijk <truedfx@gmail.com>
Date2011-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