0

How can I hold a constant value in a struct? If I put const at LEBEL0 I would not be able to assign to it at LEBEL1. But if I do not put const at LEBEL0, then I will get qualifier lost warning at LEBEL1. Is there any way to do this? I came up with a dirty solution (below) but I think there could be a better one...

    typedef struct _MyStruct
    {
        const SomePointerType pktData; <--LABEL0
    }MyStruct;

    const SomePointerType SomeFunctionICannotModify()
    {
    …
    }

    void SomeFunction()
    {
       MyStruct data;
    ….
       data.pktData = SomeFunctionICannotModify(); <--LABEL1
   ....
       SomeSubFunction(&data);
    }

    void SomeSubFunction(MyStruct* data)
    {
        this function does not modify any fields in "data".
    }

PS: The code above is a "model", not a real code, to illustrate my problem. It does not have all the codes in my actual program. Please do not ask questions like "why would you do that", "you do not have to do that", "that code does not compile" and so on.

My dirty solution

    typedef struct _ConstHolder
    {
        const SomePointerType pktData;
    }ConstHolder;

    typedef struct _MyStruct
    {
        ConstHolder holder;
    }MyStruct;

    void SomeFunction()
    {
       MyStruct data;
    ….
       ConstHolder holder = {SomeFunctionICannotModify()};
       data.holder = holder;
   ....
       SomeSubFunction(&data);
    }
Damn Vegetables
  • 11,484
  • 13
  • 80
  • 135
  • 1
    Why does it need to be const? – Hot Licks Feb 07 '14 at 01:56
  • Instead of making some fake code to "illustrate your problem", why not just make an actual short compilable example? It would have been just as easy, and much less incomprehensible. – Crowman Feb 07 '14 at 03:17

2 Answers2

0

Your question is difficult to understand, but you may be under the misapprehension that you cannot modify pktData after you've assigned to it. This is not true. Consider the following, which is perfectly legal:

const char * str = "hello";
printf("%s\n", str);
str = "goodbye";
printf("%s\n", str);

The const does not say that you cannot reassign the pointer, but instead that you cannot alter the data to which it points.

ooga
  • 15,423
  • 2
  • 20
  • 21
0

It looks to me like the problem is that you are using typedef along with const. The thing about C is that const is not as well implemented and usable as it is in C++. And typedef is not well done either.

This article talks a bit about const in C. As does this article as well on const in C.

For instance if you use the following, it will compile with no problems in Visual Studio 2005

typedef char * pchar;

typedef struct {
    int i;
    int j;
} Thing;

typedef Thing * SomePtr;

typedef struct {
//  const SomePtr pSome;
//  const pchar   mychar;
    const char * mychar;
    const Thing *pSome;
} MyStruct;

const SomePtr SomePtrFunc ()
{
    static Thing jj = {1, 2};

    return &jj;
}

int main(int argc, char **argv)
{
    MyStruct josey;

    josey.pSome = SomePtrFunc();

    josey.mychar = "this";
    return 0;
}

If I were to then try to modify what is pointed to by josey.pSome by doing something like adding a line of code such as josey.pSome->i = 0; then I will see a compilation error of error C2166: l-value specifies const object.

However if you use the following code with comments switched around, you get an error message of error C2166: l-value specifies const object

typedef char * pchar;

typedef struct {
    int i;
    int j;
} Thing;

typedef Thing * SomePtr;

typedef struct {
    const SomePtr pSome;
    const pchar   mychar;
//  const char * mychar;
//  const Thing *pSome;
} MyStruct;

const SomePtr SomePtrFunc ()
{
    static Thing jj = {1, 2};

    return &jj;
}

int main(int argc, char **argv)
{
    MyStruct josey;

    josey.pSome = SomePtrFunc();  // <- error C2166: l-value specifies const object

    josey.mychar = "this";        // <- error C2166: l-value specifies const object
    return 0;
}

Finally what you could do is to make the typedef to include the const qualifier which would then make the const qualifier part of the type:

typedef const char * pchar;

typedef struct {
    int i;
    int j;
} Thing;

typedef const Thing * SomePtr;

typedef struct {
    SomePtr pSome;
    pchar   mychar;
//  const char * mychar;
//  const Thing *pSome;
} MyStruct;
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106