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


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

Valid struct cast?

Started byThiago Adams <thiago.adams@gmail.com>
First post2017-01-13 03:28 -0800
Last post2017-01-25 14:19 +1100
Articles 7 — 6 participants

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


Contents

  Valid struct cast? Thiago Adams <thiago.adams@gmail.com> - 2017-01-13 03:28 -0800
    Re: Valid struct cast? BartC <bc@freeuk.com> - 2017-01-13 12:12 +0000
      Re: Valid struct cast? Thiago Adams <thiago.adams@gmail.com> - 2017-01-13 04:29 -0800
        Re: Valid struct cast? Barry Schwarz <schwarzb@dqel.com> - 2017-01-13 08:11 -0800
          Re: Valid struct cast? supercat@casperkitty.com - 2017-01-13 09:09 -0800
          Re: Valid struct cast? Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-14 01:01 -0800
    Re: Valid struct cast? "Peter \"Shaggy\" Haywood" <phaywood@alphalink.com.au> - 2017-01-25 14:19 +1100

#101597 — Valid struct cast?

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-13 03:28 -0800
SubjectValid struct cast?
Message-ID<2d4012cb-cb2a-4d18-9339-d3a51cb5fef2@googlegroups.com>
Is it safe to cast from 'FromArray' to 'ToArray'?

typedef struct
{
  Type1** pItems;
  int size;
  int capacity;
} FromArray;


typedef struct
{
  void** pItems;
  int size;
  int capacity;
} ToArray;

[toc] | [next] | [standalone]


#101601

FromBartC <bc@freeuk.com>
Date2017-01-13 12:12 +0000
Message-ID<o5ag3o$7hi$1@dont-email.me>
In reply to#101597
On 13/01/2017 11:28, Thiago Adams wrote:
>
> Is it safe to cast from 'FromArray' to 'ToArray'?
>
> typedef struct
> {
>   Type1** pItems;
>   int size;
>   int capacity;
> } FromArray;
>
>
> typedef struct
> {
>   void** pItems;
>   int size;
>   int capacity;
> } ToArray;

Does it work? Because I get an error compiling such a cast (from struct 
to struct). But you can do it from FromArray* to ToArray*.

Note that these structs could have been compiled with different 
struct-packing pragmas so their internal layouts might not match. 
Although that would be unlikely with this combination of fields.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#101602

FromThiago Adams <thiago.adams@gmail.com>
Date2017-01-13 04:29 -0800
Message-ID<26cc05c3-ef8e-4f56-809b-dd39898a038c@googlegroups.com>
In reply to#101601
On Friday, January 13, 2017 at 10:12:14 AM UTC-2, Bart wrote:
> On 13/01/2017 11:28, Thiago Adams wrote:
> >
> > Is it safe to cast from 'FromArray' to 'ToArray'?
> >
> > typedef struct
> > {
> >   Type1** pItems;
> >   int size;
> >   int capacity;
> > } FromArray;
> >
> >
> > typedef struct
> > {
> >   void** pItems;
> >   int size;
> >   int capacity;
> > } ToArray;
> 
> Does it work? Because I get an error compiling such a cast (from struct 
> to struct). But you can do it from FromArray* to ToArray*.

Yes, the use is for FromArray* to ToArray*.

The reason it to reuse the function of "ToArray" that works for void*
but for any other type. (Always pointers)



[toc] | [prev] | [next] | [standalone]


#101613

FromBarry Schwarz <schwarzb@dqel.com>
Date2017-01-13 08:11 -0800
Message-ID<5guh7c9dsj3sgpk4tpqh6g8ula99dl8sru@4ax.com>
In reply to#101602
On Fri, 13 Jan 2017 04:29:59 -0800 (PST), Thiago Adams
<thiago.adams@gmail.com> wrote:

>On Friday, January 13, 2017 at 10:12:14 AM UTC-2, Bart wrote:
>> On 13/01/2017 11:28, Thiago Adams wrote:
>> >
>> > Is it safe to cast from 'FromArray' to 'ToArray'?
>> >
>> > typedef struct
>> > {
>> >   Type1** pItems;
>> >   int size;
>> >   int capacity;
>> > } FromArray;
>> >
>> >
>> > typedef struct
>> > {
>> >   void** pItems;
>> >   int size;
>> >   int capacity;
>> > } ToArray;
>> 
>> Does it work? Because I get an error compiling such a cast (from struct 
>> to struct). But you can do it from FromArray* to ToArray*.
>
>Yes, the use is for FromArray* to ToArray*.
>
>The reason it to reuse the function of "ToArray" that works for void*
>but for any other type. (Always pointers)

Since all pointers to struct are required to have the same size,
alignment, and representation, casting a value of one type to the
other is not a problem.  Attempting to dereference the resulting
pointer as if it pointed to the second type can be problematic.

If the sizeof(Type1**) is not the same as sizeof(void**), members size
and capacity may not be at the same offset in the two structures.

Even if they are the same size, there is also no guarantee that a
void** can represent the value held in a Type1**.  (void** is very
much different than void* which would not have this problem.)
Similarly, there is no guarantee for the reverse.

It may work on your current system today but that is not the same as
being safe.

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#101619

Fromsupercat@casperkitty.com
Date2017-01-13 09:09 -0800
Message-ID<7c2f7ce6-4423-4aae-bc44-d3a2690fd635@googlegroups.com>
In reply to#101613
On Friday, January 13, 2017 at 10:11:52 AM UTC-6, Barry Schwarz wrote:
> Even if they are the same size, there is also no guarantee that a
> void** can represent the value held in a Type1**.  (void** is very
> much different than void* which would not have this problem.)
> Similarly, there is no guarantee for the reverse.

The C Standard allows for the existence of machines in which pointers to
different types of object have different representations.  Even when C89
was written, such machines were rare, and over the next quarter-century
they have become even moreso.  Only a tiny fraction of C programs will
ever be called upon to run on such machines.

Implementations targeting the 99%+ of platforms where all pointers use
the same representation can very cheaply offer programmers a very useful
feature: the ability to use a void** to manipulate a pointer to any kind
of object.  The C Standard does not mandate such a feature, since that
would make the language impractical to implement on platforms where
void* is represented differently from some other pointer types.  On the
other hand, the value of such feature is so readily apparent(*), and the
cost of implementing it is sufficiently low, that many compilers support
it.

(*) Among other things, it gives realloc-style functions the ability to
    move around multiple objects simultaneously.

Unfortunately, the fact that a platform could support a feature at
basically zero cost is no guarantee that implementations for that platform
will do so.  Some implementations may generate code which is unreliable when
using such constructs because the Standard doesn't require support for them
even on platforms where they would be useful.

[toc] | [prev] | [next] | [standalone]


#101726

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-01-14 01:01 -0800
Message-ID<kfn37gmnhg6.fsf@x-alumni2.alumni.caltech.edu>
In reply to#101613
Barry Schwarz <schwarzb@dqel.com> writes:

> On Fri, 13 Jan 2017 04:29:59 -0800 (PST), Thiago Adams
> <thiago.adams@gmail.com> wrote:
>
>> On Friday, January 13, 2017 at 10:12:14 AM UTC-2, Bart wrote:
>>> On 13/01/2017 11:28, Thiago Adams wrote:
>>>
>>>> Is it safe to cast from 'FromArray' to 'ToArray'?
>>>>
>>>> typedef struct
>>>> {
>>>>   Type1** pItems;
>>>>   int size;
>>>>   int capacity;
>>>> } FromArray;
>>>>
>>>>
>>>> typedef struct
>>>> {
>>>>   void** pItems;
>>>>   int size;
>>>>   int capacity;
>>>> } ToArray;
>>>
>>> Does it work?  Because I get an error compiling such a cast (from struct
>>> to struct).  But you can do it from FromArray* to ToArray*.
>>
>> Yes, the use is for FromArray* to ToArray*.
>>
>> The reason it to reuse the function of "ToArray" that works for void*
>> but for any other type.  (Always pointers)
>
> Since all pointers to struct are required to have the same size,
> alignment, and representation, casting a value of one type to the
> other is not a problem.  [...]

A 'struct A*' and a 'struct B*' will have the same alignment and
representation, but casting a 'struct A*' value to 'struct B*'
can still (theoretically) cause problems, even before the casted
value is used in any way.  I believe this conversion is what OP
was considering.  Did you mean something different?

[toc] | [prev] | [next] | [standalone]


#102448

From"Peter \"Shaggy\" Haywood" <phaywood@alphalink.com.au>
Date2017-01-25 14:19 +1100
Message-ID<53illd-6q4.ln1@walter.foo>
In reply to#101597
Please forgive the lateness of this followup.

Groovy hepcat Thiago Adams was jivin' in comp.lang.c on Fri, 13 Jan 2017
10:28 pm. It's a cool scene! Dig it.

> Is it safe to cast from 'FromArray' to 'ToArray'?
> 
> typedef struct
> {
>   Type1** pItems;
>   int size;
>   int capacity;
> } FromArray;
> 
> 
> typedef struct
> {
>   void** pItems;
>   int size;
>   int capacity;
> } ToArray;

  In short, no.
  Actually, it is not allowed. A cast operator can only be applied to
scalar (integer, floating and pointer) types, unless the resulting type
is void. You can't cast a struct to another struct.
  Chapter & verse:

  6.5.4 Cast operators

  ...

  Constraints

2       Unless the type name specifies a void type, the type name shall specify
atomic, qualified, or unqualified scalar type, and the operand shall have
scalar type.

-- 


----- Dig the NEW and IMPROVED news sig!! -----


-------------- Shaggy was here! ---------------
              Ain't I'm a dawg!!

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web