structure and constant memebers

Discussion in 'C Programming' started by ravinderthakur@gmail.com, Oct 4, 2005.

  1. Guest

    hi all experts,


    i have a structure with the constant memebers such as one given below:

    typedef struct {
    const int cbcode;
    int cberror;
    } xtsetplatestaterec;

    now in my function i want to create a stack based object for the same:

    void CreateObjectAndUseIt{
    xtsetplatestaterec plate;
    xtsetplatestaterec plate2 = {0 , 0};
    }


    now this function is giving the compilation errors while compiling on
    vc++ 6.0 since the
    cbcode memeber is a constant. the error is


    error C2512: 'xtsetbleedvaluesrec' : no appropriate default constructor
    available
    error C2552: 'tmpsetplatestaterec' : non-aggregates cannot be
    initialized with initializer list

    can anybody plz explain me what could be done to create instances of
    these objects on stack ???


    thanks
    rt
     
    , Oct 4, 2005
    #1
    1. Advertising

  2. Guest

    写é“:

    > hi all experts,
    >
    >
    > i have a structure with the constant memebers such as one given below:
    >
    > typedef struct {
    > const int cbcode;
    > int cberror;
    > } xtsetplatestaterec;
    >
    > now in my function i want to create a stack based object for the same:
    >
    > void CreateObjectAndUseIt{
    > xtsetplatestaterec plate;
    > xtsetplatestaterec plate2 = {0 , 0};
    > }
    >
    >
    > now this function is giving the compilation errors while compiling on
    > vc++ 6.0 since the
    > cbcode memeber is a constant. the error is
    >
    >
    > error C2512: 'xtsetbleedvaluesrec' : no appropriate default constructor
    > available
    > error C2552: 'tmpsetplatestaterec' : non-aggregates cannot be
    > initialized with initializer list
    >
    > can anybody plz explain me what could be done to create instances of
    > these objects on stack ???
    >
    >
    > thanks
    > rt



    why you use const there,maybe you can write like this :

    typedef struct {
    const int cbcode=0;
    int cberror;
    } xtsetplatestaterec;
     
    , Oct 4, 2005
    #2
    1. Advertising

  3. wrote:
    > hi all experts,
    >
    >
    > i have a structure with the constant memebers such as one given below:
    >
    > typedef struct {
    > const int cbcode;
    > int cberror;
    > } xtsetplatestaterec;
    >
    > now in my function i want to create a stack based object for the same:
    >
    > void CreateObjectAndUseIt{
    > xtsetplatestaterec plate;
    > xtsetplatestaterec plate2 = {0 , 0};
    > }


    The above has nothing to do with "stack based object"s. You are (quite
    legally) using local variables. There is not a sign of your use of a
    stack in sight.


    > now this function is giving the compilation errors while compiling on
    > vc++ 6.0 since the
    > cbcode memeber is a constant. the error is
    >
    >
    > error C2512: 'xtsetbleedvaluesrec' : no appropriate default constructor
    > available


    The above error message suggests you are using a C++ compiler.

    > error C2552: 'tmpsetplatestaterec' : non-aggregates cannot be
    > initialized with initializer list


    Since we can't see tmpsetplatestaterec or what you are trying to
    initialize, it is impossible to tell what you are doing wrong.

    > can anybody plz explain me what could be done to create instances of
    > these objects on stack ???


    If the code you are using is giving a problem (and you are confusing
    local variables with "objects on stack", which means nothing in C unless
    you create and maintain a stack), then stop using a C++ compiler. C and
    C++ are different languages; compiling C code as if it were C++ is
    asking for trouble.

    If you are actually trying to modify (rather than to initialize) a const
    member of a structure, then don't. Either don't modify the member or
    remove the 'const' which, after all, is a lie.
     
    Martin Ambuhl, Oct 4, 2005
    #3
  4. wrote:

    > why you use const there,maybe you can write like this :
    >
    > typedef struct {
    > const int cbcode=0;
    > int cberror;
    > } xtsetplatestaterec;


    Why would you think such a foolish thing?
     
    Martin Ambuhl, Oct 4, 2005
    #4
  5. In article <>,
    <> wrote:

    >error C2512: 'xtsetbleedvaluesrec' : no appropriate default constructor
    >available


    This appears to be a C++ error message. Probably there is some way to
    persuade your compiler to compile your program as C, perhaps by giving
    the file a name with a suitable extension.

    -- Richard
     
    Richard Tobin, Oct 4, 2005
    #5
  6. Martin Ambuhl <> writes:
    > wrote:
    >> hi all experts,
    >> i have a structure with the constant memebers such as one given
    >> below:
    >> typedef struct {
    >> const int cbcode;
    >> int cberror;
    >> } xtsetplatestaterec;
    >> now in my function i want to create a stack based object for the
    >> same:
    >> void CreateObjectAndUseIt{
    >> xtsetplatestaterec plate;
    >> xtsetplatestaterec plate2 = {0 , 0};
    >> }

    >
    > The above has nothing to do with "stack based object"s. You are
    > (quite legally) using local variables. There is not a sign of your
    > use of a stack in sight.


    To be fair, local variables are allocated on the system stack in most
    C implementations, just as malloc()-allocated objects are allocated on
    the "heap". Even though the C standard doesn't use the word "stack"
    or "heap" (I just checked), both terms can be convenient shorthands
    for automatic and allocated storage duration, respectively.

    It's worth pointing out that the standard doesn't use the term
    "stack", and that not all C implementations *necessarily* use a system
    stack in the commonly understood sense, but I don't see the need to
    pretend we don't know what it means.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Oct 4, 2005
    #6
  7. Keith Thompson wrote:

    > It's worth pointing out that the standard doesn't use the term
    > "stack", and that not all C implementations *necessarily* use a system
    > stack in the commonly understood sense, but I don't see the need to
    > pretend we don't know what it means.


    Since I *do* know what it means to maintain a stack in program, and I
    *do* know how to store objects in such a stack, it would be wrong to
    pretend that I know that the OP's use of "stack based objects" is a
    mistake for "local variables." Since I more than once allowed for the
    possibility that he suffered from such confusion, it would be dishonest
    for someone to claim that I pretended not know what that -- of more than
    one possibility -- might be what the OP poster meant. Do you purposely
    misread my posts so you can play the mis-directed anti-pedant?
     
    Martin Ambuhl, Oct 4, 2005
    #7
  8. Martin Ambuhl <> writes:
    [snip]
    > Do you purposely misread my posts so you can play the mis-directed
    > anti-pedant?


    No. If I've misread your post (which is entirely possible), it's
    unintentional.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Oct 4, 2005
    #8
  9. Martin Ambuhl <> writes:
    > Keith Thompson wrote:
    >> It's worth pointing out that the standard doesn't use the term
    >> "stack", and that not all C implementations *necessarily* use a system
    >> stack in the commonly understood sense, but I don't see the need to
    >> pretend we don't know what it means.

    >
    > Since I *do* know what it means to maintain a stack in program, and I
    > *do* know how to store objects in such a stack, it would be wrong to
    > pretend that I know that the OP's use of "stack based objects" is a
    > mistake for "local variables." Since I more than once allowed for the
    > possibility that he suffered from such confusion, it would be
    > dishonest for someone to claim that I pretended not know what that --
    > of more than one possibility -- might be what the OP poster meant. Do
    > you purposely misread my posts so you can play the mis-directed
    > anti-pedant?


    I should expand on what I wrote a moment ago.

    I assumed that the OP was using the term "stack-based objects" to
    refer to objects allocated locally to a function. I still think
    that's likely, but I made that assumption without carefully reading
    the previous articles. I also assumed that it should have been
    obvious to you, and that you were being overly pedantic, an incorrect
    assumption for which I apologize.

    Now that I've re-read the previous article, it's less clear to me just
    what the OP is asking -- especially since he seems to be using C++
    rather than C.

    Going off on a bit of a tangent, I realize I've never used, and rarely
    seen, structs with const members. It looks like this is allowed, but
    you can't provide an initial value within the struct declaration. If
    I understand this correctly, a const member can be initialized by the
    initialization of the enclosing object, but can't be re-assigned later
    without invoking undefined behavior -- and there doesn't seem to be
    any way to initialize a const member of a malloc()ed structure without
    invoking UB. This would seem to make const members not very useful.
    Perhaps they're allowed because it was easier than adding a rule to
    forbid them. Am I missing something?

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Oct 4, 2005
    #9
  10. Tim Rentsch Guest

    Keith Thompson <> writes:

    [snip]
    > Going off on a bit of a tangent, I realize I've never used, and rarely
    > seen, structs with const members. It looks like this is allowed, but
    > you can't provide an initial value within the struct declaration. If
    > I understand this correctly, a const member can be initialized by the
    > initialization of the enclosing object, but can't be re-assigned later
    > without invoking undefined behavior -- and there doesn't seem to be
    > any way to initialize a const member of a malloc()ed structure without
    > invoking UB. This would seem to make const members not very useful.
    > Perhaps they're allowed because it was easier than adding a rule to
    > forbid them. Am I missing something?


    It is possible to construct a struct with const members in a
    malloc'ed space, without UB. (Disclaimer: code has not been
    compiled.)

    ... #includes as needed ...

    struct thing {
    int a;
    const int b;
    int c;
    };

    struct thing *
    malloc_thing( int a, int b, int c ){
    void *v;
    struct thing *r;

    r = v = malloc( sizeof *r );
    if( !r ) exit( EXIT_FAILURE ); /* whatever... */

    r->a = a;
    *(int*) ((char*)v + offsetof(struct thing, b)) = b;
    r->c = c;
    return r;
    }

    Some people might squawk about the '(int*)' cast; they might want to
    use

    memcpy( (char*)v + offsetof(struct thing, b), &b, sizeof r->b );

    instead.
     
    Tim Rentsch, Oct 5, 2005
    #10
  11. On 05 Oct 2005 07:31:56 -0700, Tim Rentsch <>
    wrote:
    <snip>
    > It is possible to construct a struct with const members in a
    > malloc'ed space, without UB. (Disclaimer: code has not been
    > compiled.)
    >
    > ... #includes as needed ...
    >
    > struct thing {
    > int a;
    > const int b;
    > int c;
    > };
    >
    > struct thing *
    > malloc_thing( int a, int b, int c ){
    > void *v;
    > struct thing *r;
    >
    > r = v = malloc( sizeof *r );
    > if( !r ) exit( EXIT_FAILURE ); /* whatever... */
    >
    > r->a = a;
    > *(int*) ((char*)v + offsetof(struct thing, b)) = b;
    > r->c = c;
    > return r;
    > }
    >

    There's no need for v and offsetof; &r->b and (int*)&r->b are fine.

    > Some people might squawk about the '(int*)' cast; they might want to
    > use
    >

    No one should object to the cast as such, which is clearly a pointer
    (value) to a correctly allocated and aligned object. What some might
    object to is storing through that pointer, on the grounds the lvalue
    being used is not suitable for the actual object, although I believe
    in this case the "untypedness" of malloc-ed space saves us.

    > memcpy( (char*)v + offsetof(struct thing, b), &b, sizeof r->b );
    >
    > instead.


    Ditto, except (anynonconst*)&r->b is sufficient to pass to void* ,
    and void* specifically might be considered good documentation.
    Yes, this should squash the "wrong type for object" objection.

    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Oct 17, 2005
    #11
  12. Tim Rentsch Guest

    Dave Thompson <> writes:

    > On 05 Oct 2005 07:31:56 -0700, Tim Rentsch <>
    > wrote:
    > <snip>
    > > It is possible to construct a struct with const members in a
    > > malloc'ed space, without UB. (Disclaimer: code has not been
    > > compiled.)
    > >
    > > ... #includes as needed ...
    > >
    > > struct thing {
    > > int a;
    > > const int b;
    > > int c;
    > > };
    > >
    > > struct thing *
    > > malloc_thing( int a, int b, int c ){
    > > void *v;
    > > struct thing *r;
    > >
    > > r = v = malloc( sizeof *r );
    > > if( !r ) exit( EXIT_FAILURE ); /* whatever... */
    > >
    > > r->a = a;
    > > *(int*) ((char*)v + offsetof(struct thing, b)) = b;
    > > r->c = c;
    > > return r;
    > > }
    > >

    > There's no need for v and offsetof; &r->b and (int*)&r->b are fine.


    Yes, good point. The truth is, I just forgot about these, because my
    own development practices are so strongly predisposed to never
    "casting away" const-ness.

    Incidentally, why did you say "&r->b and (int*)&r->b"? Only
    one expression (the second one) would be used.


    > > Some people might squawk about the '(int*)' cast; they might want to
    > > use
    > >

    > No one should object to the cast as such, which is clearly a pointer
    > (value) to a correctly allocated and aligned object. What some might
    > object to is storing through that pointer, on the grounds the lvalue
    > being used is not suitable for the actual object, although I believe
    > in this case the "untypedness" of malloc-ed space saves us.


    I believe no reasonable person would object either to the '(int *)'
    cast or to storing through the resultant pointer value. I put in
    the alternative only to avoid an irrelevant tangential discussion
    about the possible legalities or non-legalities. Not that such
    nitpicking would ever occur in comp.lang.c.


    > > memcpy( (char*)v + offsetof(struct thing, b), &b, sizeof r->b );
    > >
    > > instead.

    >
    > Ditto, except (anynonconst*)&r->b is sufficient to pass to void* ,
    > and void* specifically might be considered good documentation.
    > Yes, this should squash the "wrong type for object" objection.


    Legally, you're right.

    Stylistically, writing '(void*) &r->b' fails my "what reaction would I
    expect during code review?" test. It works, but for reasons that are
    deceptive or at best obscure. An alternative that might be better:

    #define dangerous_memcpy(d,s,n) (memcpy( (void*)(d), (s), (n) ))

    ...

    dangerous_memcpy( &r->b, &b, sizeof r->b );
     
    Tim Rentsch, Oct 18, 2005
    #12
  13. On 17 Oct 2005 19:36:13 -0700, Tim Rentsch <>
    wrote:

    > Dave Thompson <> writes:
    >
    > > On 05 Oct 2005 07:31:56 -0700, Tim Rentsch <>

    <snip>
    > > > *(int*) ((char*)v + offsetof(struct thing, b)) = b;

    <snip>
    > > There's no need for v and offsetof; &r->b and (int*)&r->b are fine.

    >
    > Yes, good point. The truth is, I just forgot about these, because my
    > own development practices are so strongly predisposed to never
    > "casting away" const-ness.
    >
    > Incidentally, why did you say "&r->b and (int*)&r->b"? Only
    > one expression (the second one) would be used.
    >

    Well, the latter includes the former so you're using both. <G> I have
    a bias toward generalizing or noting related cases so as to avoid
    implication that because I omitted something it isn't covered or isn't
    the same, especially with my delay in reading and replying to news.
    But I agree the latter is the one whose validity is (more) important.

    >
    > > > Some people might squawk about the '(int*)' cast; they might want to
    > > > use
    > > >

    > > No one should object to the cast as such, which is clearly a pointer
    > > (value) to a correctly allocated and aligned object. What some might
    > > object to is storing through that pointer, on the grounds the lvalue
    > > being used is not suitable for the actual object, although I believe
    > > in this case the "untypedness" of malloc-ed space saves us.

    >
    > I believe no reasonable person would object either to the '(int *)'
    > cast or to storing through the resultant pointer value. I put in
    > the alternative only to avoid an irrelevant tangential discussion
    > about the possible legalities or non-legalities. Not that such
    > nitpicking would ever occur in comp.lang.c.
    >

    I think both objections are wrong, but distinguishable. The pointer
    (value) cast is to my reading clearly allowed by direct positive
    wording; I don't see _any_ counterargument. The store on its face
    triggers the rules about storing into objects and particularly const
    objects. In practice the fact that malloc space must be contiguous and
    most of it writable means that an implementation couldn't enforce
    constness of a subobject in it, and I _think_ the formal reflection of
    this should be read to formally affirm it, but I can see that a
    counterargument _could_ be made.

    <snip: or memcpy>
    > > Ditto, except (anynonconst*)&r->b is sufficient to pass to void* ,
    > > and void* specifically might be considered good documentation.
    > > Yes, this should squash the "wrong type for object" objection.

    >
    > Legally, you're right.
    >
    > Stylistically, writing '(void*) &r->b' fails my "what reaction would I
    > expect during code review?" test. It works, but for reasons that are
    > deceptive or at best obscure. An alternative that might be better:
    >

    I'm not sure about that. Semantically, I need to pass to memcpy a
    pointer to the memory as nonconst but I don't otherwise care _here_
    about the type. I think void* expresses that reasonably, and so does
    char*. And so does int*, except it does care about the type. If there
    were a shop or project style applicable to this I would conform, but I
    don't see anything a priori bad about any of these.

    > #define dangerous_memcpy(d,s,n) (memcpy( (void*)(d), (s), (n) ))
    >

    That's certainly an option, although I would probably go with a macro
    only if this situation occurs more than a few times in the code --
    which I hope it doesn't.

    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Oct 24, 2005
    #13
  14. Tim Rentsch Guest

    Dave Thompson <> writes:

    > On 17 Oct 2005 19:36:13 -0700, Tim Rentsch <>
    > wrote:
    >
    > > Dave Thompson <> writes:
    > >

    > <snip: or memcpy>
    > > > Ditto, except (anynonconst*)&r->b is sufficient to pass to void* ,
    > > > and void* specifically might be considered good documentation.
    > > > Yes, this should squash the "wrong type for object" objection.

    > >
    > > Legally, you're right.
    > >
    > > Stylistically, writing '(void*) &r->b' fails my "what reaction would I
    > > expect during code review?" test. It works, but for reasons that are
    > > deceptive or at best obscure. An alternative that might be better:
    > >

    > I'm not sure about that. Semantically, I need to pass to memcpy a
    > pointer to the memory as nonconst but I don't otherwise care _here_
    > about the type. I think void* expresses that reasonably, and so does
    > char*. And so does int*, except it does care about the type. If there
    > were a shop or project style applicable to this I would conform, but I
    > don't see anything a priori bad about any of these.


    Actually I think we might be closer on this than it might seem.
    By my question, I don't mean that I think it would fail the code
    review necessarily, only that it might be brought up; if I can
    avoid spending code review capital on this line, there's more to
    spend other places. So the code review test question can be seen
    as overly stringent; but sometimes it's good to be more
    stringent than is strictly necessary.
     
    Tim Rentsch, Oct 26, 2005
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Christopher M. Lusardi
    Replies:
    1
    Views:
    4,136
  2. G Patel
    Replies:
    8
    Views:
    376
  3. Replies:
    4
    Views:
    359
    Keith Thompson
    Dec 14, 2006
  4. ravinder thakur

    structure and constant memebers

    ravinder thakur, Oct 4, 2005, in forum: C++
    Replies:
    1
    Views:
    345
    Milind
    Oct 4, 2005
  5. G G
    Replies:
    3
    Views:
    116
    Ben Bacarisse
    Apr 20, 2014
Loading...

Share This Page