l i n u x - u s e r s - g r o u p - o f - d a v i s
L U G O D
 
Next Meeting:
August 5: Social gathering
Next Installfest:
TBD
Latest News:
Jul. 4: July, August and September: Security, Photography and Programming for Kids
Page last updated:
2006 Jun 04 12:04

The following is an archive of a post made to our 'vox-tech mailing list' by one of its subscribers.

Report this post as spam:

(Enter your email address)
Re: [vox-tech] C - passing chars and pointer to chars
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [vox-tech] C - passing chars and pointer to chars



On Sat 03 Jun 06, 10:27 PM, Ken Bloom <kbloom@gmail.com> said:
> 
> Cue, the **Fundemental axiom of the C++ type system**, stated as 
> follows:
>   A* is automaitcally convertable to B* if and only if A is a B.
>   (Likewise for pass by reference).
> 
> (this is my own generalization though, and there may actually be 
> exceptions)
> 
> When handling inheritance, if Derived is a Base (Derived inherits from 
> Base), then Derived* can be automatically converted to Base*. But a 
> Derived* is not a Base*, so a Derived** cannot be automatically 
> converted to a Base**.
> 
> When dealing with templates, you cannot pass vector<Derived> where a 
> vector<Base> is expected, neither by reference nor by pointer, because 
> vector<Derived> is not a vector<Base> (because if you were to stick a 
> new Base into the vector, then it would violate the type of 
> vector<Derived>).
> 
> Supposing you wanted to create a new reference_counted_pointer<T>. A 
> reference_counted_pointer<Derived> is not a 
> reference_counted_pointer<Base>, and cannot be used as such, but you 
> would want to implement all of the appropriate conversions when writing 
> reference_counted_pointer<T> to mimic the semantics of an ordinary 
> pointer.
> 
> signed char is not an unsigned char, but they are convertable. However, 
> signed char * is not convertable to unsigned char *, and to force such 
> a conversion, you would use a reinterpret_cast<> (which reinterprets 
> the actual bits according to a different time), or as it seems from 
> Bill's post, a static_cast<> (which is generally safer when it's 
> allowed).
> 
> --Ken Bloom

Although this was interesting to read, it doesn't say much other than to
restate my observation in a more sophisticated way.

I gave good reasons *why* passing the pointers should always work.  I think
Micah really got at the heart of the matter:


   Micah said:
   Pointers to incompatible types are not guaranteed to be represented the
   same way, even though in practice they are. /All/ pointer types must be
   convertible to and from a pointer to any character type, and used as
   such, so this makes it all the more likely that they will be represented
   the same.

   Irregardless, the Standard does /require/ that a warning be given when
   you try to do this.


I think the  main point is the lack of guarantee that they're represented
the same way.  Here's what I think he means.

I *think* what Micah is saying here is that even though a char and signed
char types have the same width (1 byte) and are implemented the same way in
practise, there's no guarantee that they *are* implemented the same way.

For example, a perverse compiler writer may put a byte of dead storage (for
whatever reason) in between contiguous elements of a char array and 2 bytes
of dead storage in between contiguous elements of a signed char array.

The only guarantees are:

1. a char and signed char provide only one byte of storage.
2. ++(char *) will point to the next element of a char array.
3. ++(signed char *) will point to the next element of a signed
      char array.

and that's it.  In the scenario of the perverse compiler writer, if you made
a "char *" point to a "signed char" array, if you added one to the char
pointer, it won't quite reach the next element of the signed char array:


   signed char ar[5];
   char *c_ptr = ar;
   ++c_ptr;


memory              *        *        *        *        *        *
char array          [0]               [1]               [2]
signed char array   [0]                        [1]
                     ^                ^
                     |                |
                   c_ptr           ++c_ptr

As long as each element only provides one byte of storage, and that adding
one to the respective array worked, the standard will be satisfied.

In practise, char and signed char arrays are always implemented as:


memory              *        *        *        *        *
char array          [0]      [1]      [2]      [3]      [4]
signed char array   [0]      [1]      [2]      [3]      [4]
                     ^        ^
                     |        |
                   c_ptr   ++c_ptr



but the standard doesn't guarantee this, which is why passing different
types of char pointers works in practise, but is not absolutely guaranteed
by the standard to work.

At least, this is how I read Micah's response.  Maybe it's not correct.  :)
If this is approximately correct, then the warning makes complete sense,
even though in practise, it's not necessary.

Pete
_______________________________________________
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech



LinkedIn
LUGOD Group on LinkedIn
Sign up for LUGOD event announcements
Your email address:
facebook
LUGOD Group on Facebook
'Like' LUGOD on Facebook:

Hosting provided by:
Sunset Systems
Sunset Systems offers preconfigured Linux systems, remote system administration and custom software development.

LUGOD: Linux Users' Group of Davis
PO Box 2082, Davis, CA 95617
Contact Us

LUGOD is a 501(c)7 non-profit organization
based in Davis, California
and serving the Sacramento area.
"Linux" is a trademark of Linus Torvalds.

Sponsored in part by:
O'Reilly and Associates
For numerous book donations.