Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > const members

Reply
Thread Tools

const members

 
 
S.Tobias
Guest
Posts: n/a
 
      11-16-2004
1. If I have a struct type which contains a const member:
struct mystruct
{
const int id;
int mutable;
};
does a definition
struct mystruct ms;
define an object `ms' which is *partly* const? Ie. the object `ms'
is not const as a whole, but modifying ms.id yields UB in all contexts?

2. Provided the answer to the above question is "yes" (ms.id is really
a const (sub)object), would the below code work:

struct mystruct_without_const
{
int id;
int mutable;
};

struct mystruct *new_mystruct(void)
{
struct mystruct_without_const *msp;
msp = malloc(sizeof *msp);
if (msp)
{
msp->id = /*generate id*/; /*well defined*/
msp->mutable = /*...*/;
}
return (struct mystruct*)msp;
}

(In above code I try to create a non-const struct object, initialize
supposed-to-be-const members in a well defined manner, and return a
pointer to the object where some members are "constified".)

Is there some kind of layout compatibility between mystruct and
mystruct_without_const?

--
Stan Tobias
sed 's/[A-Z]//g' to email
 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      11-16-2004
"S.Tobias" <> wrote:

> 1. If I have a struct type which contains a const member:
> struct mystruct
> {
> const int id;
> int mutable;
> };
> does a definition
> struct mystruct ms;
> define an object `ms' which is *partly* const? Ie. the object `ms'
> is not const as a whole, but modifying ms.id yields UB in all contexts?


Yes. So unless you initialise it, ms.id contains garbage, can't be given
a reliable value, and is completely useless.

> 2. Provided the answer to the above question is "yes" (ms.id is really
> a const (sub)object), would the below code work:
>
> struct mystruct_without_const
> {
> int id;
> int mutable;
> };


> Is there some kind of layout compatibility between mystruct and
> mystruct_without_const?


Yes. 6.2.5#25:
# The qualified or unqualified versions of a type are distinct types
# that belong to the same type category and have the same representation
# and alignment requirements.39)
# 39) The same representation and alignment requirements are meant to
# imply interchangeability as arguments to functions, return values from
# functions, and members of unions.

I foresee some problems with your method, though; in particular, that
using malloc() is over-complicated, since you can assign (and therefore
use as a return value) structs, just as any other basic type.

Richard
 
Reply With Quote
 
 
 
 
Lawrence Kirby
Guest
Posts: n/a
 
      11-16-2004
On Tue, 16 Nov 2004 11:39:52 +0000, S.Tobias wrote:

> 1. If I have a struct type which contains a const member:
> struct mystruct
> {
> const int id;
> int mutable;
> };
> does a definition
> struct mystruct ms;
> define an object `ms' which is *partly* const?


There are 2 concepts to consider here, one is whether it is const i.e.
whether its type is const qualified. ms does not have a const qualified
type. The other is whether ms is "modifiable". A const object is
non-modifiable and because id has a non-modifiable member it is
non-modifiable as a whole, which means that things like

ms = another_mystruct;

result in undefined behaviour.

> Ie. the object `ms'
> is not const as a whole, but modifying ms.id yields UB in all contexts?


Yes modifying ms and ms.id result in UB where the latter is not a direct
constraint violation. Modifying ms.mutable is OK however.

> 2. Provided the answer to the above question is "yes" (ms.id is really
> a const (sub)object), would the below code work:
>
> struct mystruct_without_const
> {
> int id;
> int mutable;
> };
>
> struct mystruct *new_mystruct(void)
> {
> struct mystruct_without_const *msp;
> msp = malloc(sizeof *msp);
> if (msp)
> {
> msp->id = /*generate id*/; /*well defined*/
> msp->mutable = /*...*/;
> }
> return (struct mystruct*)msp;
> }
>
> (In above code I try to create a non-const struct object, initialize
> supposed-to-be-const members in a well defined manner, and return a
> pointer to the object where some members are "constified".)
>
> Is there some kind of layout compatibility between mystruct and
> mystruct_without_const?


Unfortunately struct mystruct_without_const and struct mystruct are
not compatible types, which pretty much means there are no requirements
for consistency of representation.

Lawrence
 
Reply With Quote
 
suman kar
Guest
Posts: n/a
 
      11-17-2004
(Richard Bos) wrote in message news:<>...
> "S.Tobias" <> wrote:
>
> > 1. If I have a struct type which contains a const member:
> > struct mystruct
> > {
> > const int id;
> > int mutable;
> > };
> > does a definition
> > struct mystruct ms;
> > define an object `ms' which is *partly* const? Ie. the object `ms'
> > is not const as a whole, but modifying ms.id yields UB in all contexts?

>
> Yes. So unless you initialise it, ms.id contains garbage, can't be given
> a reliable value, and is completely useless.
>
> > 2. Provided the answer to the above question is "yes" (ms.id is really
> > a const (sub)object), would the below code work:
> >
> > struct mystruct_without_const
> > {
> > int id;
> > int mutable;
> > };

>
> > Is there some kind of layout compatibility between mystruct and
> > mystruct_without_const?

>
> Yes. 6.2.5#25:
> # The qualified or unqualified versions of a type are distinct types
> # that belong to the same type category and have the same representation
> # and alignment requirements.39)
> # 39) The same representation and alignment requirements are meant to
> # imply interchangeability as arguments to functions, return values from
> # functions, and members of unions.
>
> I foresee some problems with your method, though; in particular, that
> using malloc() is over-complicated, since you can assign (and therefore
> use as a return value) structs, just as any other basic type.
>
> Richard


Hi,

What I understand is:
1.`struct mystruct' and `mystruct_without_const' are distinct types
2.Now 6.2.5#25 says "The qualified or unqualified versions of a type..."
which implies (for me) something like

const struct mystruct something;
struct mystruct somethingElse;

have "The same representation and alignment requirements ..."
and so do:

const struct mystruct_without_const something2;
struct mystruct_without_const somethingElse2;

But that does not imply(for me)that the two structs have same alignment
requirements etc.

Am I wrong in my interpretation?Please explain.

Regards,
Suman.
 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      11-17-2004
(suman kar) wrote:

> (Richard Bos) wrote in message news:<>...
> > "S.Tobias" <> wrote:
> >
> > > Is there some kind of layout compatibility between mystruct and
> > > mystruct_without_const?

> >
> > Yes. 6.2.5#25:
> > # The qualified or unqualified versions of a type are distinct types
> > # that belong to the same type category and have the same representation
> > # and alignment requirements.39)
> > # 39) The same representation and alignment requirements are meant to
> > # imply interchangeability as arguments to functions, return values from
> > # functions, and members of unions.


> What I understand is:
> 1.`struct mystruct' and `mystruct_without_const' are distinct types
> 2.Now 6.2.5#25 says "The qualified or unqualified versions of a type..."
> which implies (for me) something like
>
> const struct mystruct something;
> struct mystruct somethingElse;
>
> have "The same representation and alignment requirements ..."
> and so do:
>
> const struct mystruct_without_const something2;
> struct mystruct_without_const somethingElse2;
>
> But that does not imply(for me)that the two structs have same alignment
> requirements etc.


Erm... yes. That rule is for entire structs, not for structs with const
members. My fault; please ignore that post.

Richard
 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      11-17-2004
suman kar wrote:

> (Richard Bos) wrote in message news:<>...
>
>>"S.Tobias" <> wrote:
>>
>>
>>>1. If I have a struct type which contains a const member:
>>> struct mystruct
>>> {
>>> const int id;
>>> int mutable;
>>> };
>>>does a definition
>>> struct mystruct ms;
>>>define an object `ms' which is *partly* const? Ie. the object `ms'
>>>is not const as a whole, but modifying ms.id yields UB in all contexts?

>>
>>Yes. So unless you initialise it, ms.id contains garbage, can't be given
>>a reliable value, and is completely useless.
>>
>>
>>>2. Provided the answer to the above question is "yes" (ms.id is really
>>>a const (sub)object), would the below code work:
>>>
>>> struct mystruct_without_const
>>> {
>>> int id;
>>> int mutable;
>>> };

>>
>>
>>
>>>Is there some kind of layout compatibility between mystruct and
>>>mystruct_without_const?

>>
>>Yes. 6.2.5#25:
>># The qualified or unqualified versions of a type are distinct types
>># that belong to the same type category and have the same representation
>># and alignment requirements.39)
>># 39) The same representation and alignment requirements are meant to
>># imply interchangeability as arguments to functions, return values from
>># functions, and members of unions.
>>
>>I foresee some problems with your method, though; in particular, that
>>using malloc() is over-complicated, since you can assign (and therefore
>>use as a return value) structs, just as any other basic type.
>>
>>Richard

>
>
> Hi,
>
> What I understand is:
> 1.`struct mystruct' and `mystruct_without_const' are distinct types


Yep. One a non-modifiable, one a modifiable lvalue.
The types are not compatible.

> 2.Now 6.2.5#25 says "The qualified or unqualified versions of a type..."
> which implies (for me) something like
>
> const struct mystruct something;
> struct mystruct somethingElse;
>
> have "The same representation and alignment requirements ..."
> and so do:
>
> const struct mystruct_without_const something2;
> struct mystruct_without_const somethingElse2;


It also implies
const int fixed;
int nonfixed;
to have the same representation and alignment requirements.

> But that does not imply(for me)that the two structs have same alignment
> requirements etc.


The structs are built up using the member types' alignment requirements.
As const int and int are treated the same, the structs should have the
same representation.


Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      11-17-2004
On Tue, 16 Nov 2004 20:27:42 -0800, suman kar wrote:

....

> Hi,
>
> What I understand is:
> 1.`struct mystruct' and `mystruct_without_const' are distinct types


Specifically they are incompatible types.

> 2.Now 6.2.5#25 says "The qualified or unqualified versions of a type..."
> which implies (for me) something like
>
> const struct mystruct something;
> struct mystruct somethingElse;
>
> have "The same representation and alignment requirements ..."
> and so do:
>
> const struct mystruct_without_const something2;
> struct mystruct_without_const somethingElse2;


Yes.

>
> But that does not imply(for me)that the two structs have same alignment
> requirements etc.


It would take a pathological implementation to represent the two
structures differently, but it is perfectly possible despite what the
footnote in the standard implies. Padding between structure members has
to provide suitable alignment for those members but isn't defined
solely in terms of that, other factors can be takien into consideration.
For example consider an array of 3 characters. That has to have 1 byte
alignment (or I suppose 3 in theory) requirements or else

char a[4][3];

wouldn't work. But a compiler might decide there are advantages to
aligning a structure member that is an array of 3 chars to 4 byte
boundaries.

Lawrence
 
Reply With Quote
 
S.Tobias
Guest
Posts: n/a
 
      11-18-2004
Richard Bos <> wrote:

> I foresee some problems with your method, though; in particular, that
> using malloc() is over-complicated,


I'm not sure I understand why you say "over-complicated"; think of
new_mystruct() as an allocator and constructor
(C++: mystruct *msp = new mystruct.

I'll continue in reply to Lawrence Kirby.

--
Stan Tobias
sed 's/[A-Z]//g' to email
 
Reply With Quote
 
S.Tobias
Guest
Posts: n/a
 
      11-18-2004
Lawrence Kirby <> wrote:
> On Tue, 16 Nov 2004 11:39:52 +0000, S.Tobias wrote:


What I'm trying is to explore a possibility of creating a non-const
object and returning it to a client in such a form that it's partly
consted. Similarly to:
const char *get_const_buffer(void) /*return ptr to const-buffer*/
{
static char buffer[ENOUGH]; /*non-const object*/
return buffer;
}
but I want it only partly consted.

I'm thinking of having a pool of transparent struct type objects,
which could be reused. I forbid (well... at least make it harder)
the client to modify certain fields (`id') by designating them `const'.
But in order to reuse the object (to avoid free()/malloc()) the object
itself must be non-const, so that the library can regenerate `id' when
another object is requested.

(My aim would be achieved by making an opaque type and supplying
accessor functions (C++ way), but simplicity has its merits too and
I want to find out if "const" scheme would work.)


> > 1. If I have a struct type which contains a const member:
> > struct mystruct
> > {
> > const int id;
> > int mutable;
> > };
> > does a definition
> > struct mystruct ms;
> > define an object `ms' which is *partly* const?


> There are 2 concepts to consider here, one is whether it is const i.e.
> whether its type is const qualified. ms does not have a const qualified
> type. The other is whether ms is "modifiable". A const object is
> non-modifiable and because id has a non-modifiable member it is
> non-modifiable as a whole, which means that things like


Thanks for brining my attention to it.

A small nit-pick: you talk of "non-modifiable object". As I understand
it, objects may be const, but lvalues (expressions designating an object)
may be modifiable; eg. we may (try to) modify const object through
a modifiable lvalue (UB), or try to modyfy non-const object through
non-modifiable lvalue (constraint violation). Constness belongs to
objects and types, modifiability belongs to type system.
Please correct me if I'm wrong.

> ms = another_mystruct;


> result in undefined behaviour.


Or in diagnostics?


> > Ie. the object `ms'
> > is not const as a whole, but modifying ms.id yields UB in all contexts?


> Yes modifying ms and ms.id result in UB where the latter is not a direct
> constraint violation.


Could you please tell me how to derive it from the Standard; I think
it's not quite obvious. (I do believe you, it's just that I'm curious
and I want to learn.)


I think in my previous post I might have made an error in my thinking.
The buffer obtained from malloc() is not a const-object and I probably
don't need mystruct_without_const at all.

Please, have a look at my new code:

struct mystruct *new_mystruct(void)
{
struct mystruct *msp;
msp = malloc(sizeof *msp);
if (msp)
{
*(int*)& msp->id = /*generate id*/; /*well defined?*/
msp->mutable = /*...*/;
}
return msp;
}

Is that whole cast operation (simply meant to be in
C++ speak: const_cast<int&>) correct?

What effective type will the allocated buffer have after return?


--
Stan Tobias
sed 's/[A-Z]//g' to email
 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      11-18-2004
On Thu, 18 Nov 2004 14:45:01 +0000, S.Tobias wrote:

....

> I'm thinking of having a pool of transparent struct type objects, which
> could be reused. I forbid (well... at least make it harder) the client
> to modify certain fields (`id') by designating them `const'. But in
> order to reuse the object (to avoid free()/malloc()) the object itself
> must be non-const, so that the library can regenerate `id' when another
> object is requested.
>
> (My aim would be achieved by making an opaque type and supplying
> accessor functions (C++ way), but simplicity has its merits too and I
> want to find out if "const" scheme would work.)



Structly, no, but it would take a very unreasonable implementation to
break this, even the standard suggests that in footnotes.

IMHO this is the sort of thing you document the assumption and just go
ahead. Like assuming that EOF is distinct from the values returned by
getc() for all valid characters (although nobody I know of documents
that).

>> > 1. If I have a struct type which contains a const member:
>> > struct mystruct
>> > {
>> > const int id;
>> > int mutable;
>> > };
>> > does a definition
>> > struct mystruct ms;
>> > define an object `ms' which is *partly* const?

>
>> There are 2 concepts to consider here, one is whether it is const i.e.
>> whether its type is const qualified. ms does not have a const qualified
>> type. The other is whether ms is "modifiable". A const object is
>> non-modifiable and because id has a non-modifiable member it is
>> non-modifiable as a whole, which means that things like

>
> Thanks for brining my attention to it.
>
> A small nit-pick: you talk of "non-modifiable object". As I understand
> it, objects may be const, but lvalues (expressions designating an
> object) may be modifiable; eg. we may (try to) modify const object
> through a modifiable lvalue (UB), or try to modyfy non-const object
> through non-modifiable lvalue (constraint violation). Constness belongs
> to objects and types, modifiability belongs to type system. Please
> correct me if I'm wrong.


You are correct that modifiable lvalue is a specific term defined by the
standard. I quoted my use of modifiable in eference to objects as it is my
own. It is reasonable to think of const defined objects and strin literal
objects as non-modifiable, the standard just says you get undefined
behaviour if you try to modify them.

const is just a type, i.e. compile time, concept. At runtime the issue is
whether something bad could happen if you try to write to an object, which
isn't the same as constness, although constness in the source code will
allow such badness.

>> ms = another_mystruct;

>
>> result in undefined behaviour.

>
> Or in diagnostics?


Yes, you are correct - this requires a diagnostic. The LHS of an
assignment must be a modifiable lvalue and that can't be a structure type
with any (recursively) const members.

>> > Ie. the object `ms'
>> > is not const as a whole, but modifying ms.id yields UB in all
>> > contexts?

>
>> Yes modifying ms and ms.id result in UB where the latter is not a
>> direct constraint violation.

>
> Could you please tell me how to derive it from the Standard; I think
> it's not quite obvious. (I do believe you, it's just that I'm curious
> and I want to learn.)


Since I was wrong that's tricky. For the diagnostic you have the
constraint of C99 6.5.16 and the definition of modifiable lvalue
6.3.2.1p1. FOr UB in other const cases the reference is C99 6.7.3p5.

> I think in my previous post I might have made an error in my thinking.
> The buffer obtained from malloc() is not a const-object and I probably
> don't need mystruct_without_const at all.


Makes sense.

> Please, have a look at my new code:
>
> struct mystruct *new_mystruct(void)
> {
> struct mystruct *msp;
> msp = malloc(sizeof *msp);
> if (msp)
> {
> *(int*)& msp->id = /*generate id*/; /*well defined?*/


Looks good to me.

> msp->mutable = /*...*/;
> }
> return msp;
> }
> }
> Is that whole cast operation (simply meant to be in C++ speak:
> const_cast<int&>) correct?
>
> What effective type will the allocated buffer have after return?


AFAICS the caller code could modify the id member with
appropriate casting as you have done above and not onvoke UB. I can't see
that as a problem though. I think that's a that's significant here in
terms of "effective type".


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Resolving ambiguity between pointers to const and non-const members. Vladimir Menshakov C++ 1 05-15-2011 08:15 AM
is const necessary in eg int compar(const void *, const void *) lovecreatesbeauty@gmail.c0m C Programming 26 11-10-2008 09:47 PM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Casting int'** to 'const int * const * const' dosn't work, why? Jonas.Holmsten@gmail.com C Programming 11 07-01-2007 06:16 PM
About static const members appearing in another static const definitions Rakesh Sinha C++ 4 01-13-2005 08:11 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57