Topic: properties of scalar objects w/ indeterminate value //iterator


Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Mon, 9 Dec 2002 00:30:42 +0000 (UTC)
Raw View
Markus Mauhart wrote:
....
> And probably the same then is true for C99, e.g. copying a pointer p
> 'initialized' only via "T* p;" is undefined behaviour, right ?

Yes. In fact, C99 is far clearer about this. C99 adds the concept of
trap representations. For any type that can have trap representations,
an uninitialized object of that type might contain a trap
representation. The effect of this is pretty much the same as the rules
for the use of uninitialized objects in C++. However, C99 makes it clear
which types are allowed to have trap representations; it's perfectly
safe to read, copy, and compare uninitialized objects of the types that
can't have trap representations. All signed integer types, pointer
types, and floating point types are allowed to have trap
representations. So are all of the unsigned integer types except
unsigned char and the new exact-width typedefs such as uint32_t.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Tue, 10 Dec 2002 05:20:24 +0000 (UTC)
Raw View
Markus Mauhart wrote:
> "James Kuyper Jr." <kuyper@wizard.net> wrote ...
....
> Very interesting ! Originally I thought of that C that is/was relevant
> for c++98, but C99 probably has more details on complicated issues.

That's my impression; C99 has more thoroughly thought out details, while
C++98 has a lot more features. This makes sense, because  C99 was a
rewrite. C++98 was a brand new standard, and was a major change from the
closest thing there was to a prior standard, so they didn't have as much
time to refine the the descriptions.

....
> BTW, from C99 I couldnt find out how conversion (-> copy, assignment)
> between compound type objects is done: recursive copying of members
> (like c++) or "memcopy(dst,src,sizeof(both))" ?

It took me a long time to find the relevant clause; it's not in any
location I'd have expected it to be in.

C99 6.2.6.1: "When a value is stored in an object of structure or union
type, ... the bytes of the object representation that correspond to any
padding bytes take unspecified values. 42)"

Footnote 42: "Thus, for example, structure assignment may be implemented
element-at-a-time or via memcpy."

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net ("James Kuyper Jr.")
Date: Thu, 5 Dec 2002 20:42:26 +0000 (UTC)
Raw View
Markus Mauhart wrote:
> "John Potter" <jpotter@falcon.lhup.edu> wrote ...
>
>>You should never do anything other than assign a new value with a
>>default constructed iterator.  It is just like int* p;
>
>
> AFAICS there are significant differences between iterators
> with required def-ctor and 'un-initialized' raw pointers:
>
> iterator i, j           ;//both may be 'singular'
> i == i                  ;//undefined behaviour. (OK for pointers ?)
> j =  i                  ;//undefined behaviour. OK for pointers
> j == i                  ;//undefined behaviour. (OK for pointers ?)
 >
> iterator k = iterator() ;//undefined behaviour. OK for pointers
> iterator l(i)           ;//undefined behaviour. OK for pointers
>
> AFAICS this kind of well defined "copy/assignment between same types"
> applies to all 'un-initialized' ('indeterminate value') scalar types.

None of the above expressions work for pointers. See section 4.1: "If
.... the object is uninitialized, a program which requires this [lvalue
to rvalue] conversion has undefined behavior". Copy assignment between
same types requires lvalue to rvalue conversion for the copied object;
if that object is uninitialized, it has undefined behavior.

> What is not clear for me is whether one may compare such things
> to certain other things. Naively one might guess that all such
> copies of an indeterminate value must compare equal and not !=,

If you hadn't read 4.1, that is.

> especially not raising an exception or formatting the disk !
>
> That leds me to the question what generally is allowed
> for scalar type objects with indeterminate values:
>
> typedef int*_or_double S;
> S s    ;//non-static -> indeterminate value.

That's fine; no lvalue-to-rvalue conversion.

> s == s ;//true or indeterminate result or undefined behaviour ?
> S t = s;//8.5,par14: the initial value of the object being initialized
>         //is the (possibly converted) value of the initializer expression.
>         // => not undefined behaviour; "same value".
> t == s ;//true or indeterminate result or undefined behaviour ?
> t = s  ;// => not undefined behaviour; "same value".
> t == s ;//true or indeterminate result or undefined behaviour ?

Every single one of those requires lvalue-to-rvalue conversion for the
right operand, and thus has undefined behavior.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]