How do you initialize a dynamic structure that has a const data member? I can provide an ugly hack but I'm at a loss as how to do it correctly. Actually, can you do this in a platform independent way?

#include <stdio.h>
#include <stdlib.h>

struct mys
{
  const int value;
};

int main(int argc, char**argv)
{
  struct mys *sptr = (struct mys*)malloc(sizeof(struct mys));
  
  *(int*)sptr = 1234;
  
  fprintf(stdout, "ans->%d\n", sptr->value);
  
  /*sptr->value = 67;*/
  return 0;
}

Edited 5 Years Ago by gerard4143: n/a

I don't know how to initialize it, but try this and your solution doesn't work. My suggestion is not to put const variables inside structures. It wouldn't make any sense to put them inside a structure anyway because by definition you set a const variable to a single value which does not depend on any given instance of the structure. const variables have the same value for all instances of the structure and can never be legally changed. Of course you can typecast out the const and change it that way, but that's cheating.

struct mys
{
    char buf[255];
    const int value;
};

Edited 5 Years Ago by Ancient Dragon: n/a

I don't know how to initialize it, but try this and your solution doesn't work. My suggestion is not to put const variables inside structures. It wouldn't make any sense to put them inside a structure anyway because by definition you set a const variable to a single value which does not depend on any given instance of the structure. const variables have the same value for all instances of the structure and can never be legally changed. Of course you can typecast out the const and change it that way, but that's cheating.

struct mys
{
    char buf[255];
    const int value;
};

Oh, I'm aware of the limitations of that solution. That's the primary reason for posting the question.

#include <stddef.h>
...
    * (int *) (((char *) sptr) + offsetof(struct mys, value)) = 1234;

Nice solution but it still assumes that the const int can be hacked around.

Edited 5 Years Ago by gerard4143: n/a

Of course. I do not expect it to be compliant; the Standard pretty much says that const qualification forbids the qualifiee (for a lack of the better word) to be a modifiable lvalue. It even makes it viral, in a sense of 6.3.2.1-1, which already makes allocation in your original snippet noncompliant. If I am right in my interpretation, my proposal wouldn't do any more harm.

Edited 5 Years Ago by nezachem: n/a

Of course. I do not expect it to be compliant; the Standard pretty much says that const qualification forbids the qualifiee (for a lack of the better word) to be a modifiable lvalue. It even makes it viral, in a sense of 6.3.2.1-1, which already makes allocation in your original snippet noncompliant. If I am right in my interpretation, my proposal wouldn't do any more harm.

In C++ the solution is simple with the use of constructors but I don't think you can allocate and initialize constants within the C framework or at least I can't find any way. Thanks for the input.

Edited 5 Years Ago by gerard4143: n/a

Sorry I am too late. The right way is indeed to use a constructor like this:

struct foo { const int value; };
struct relaxed_foo { int value; };
struct foo * init_foo(int value) {
    struct relaxed_foo * rc = malloc(sizeof(struct foo));
    rc->value = value;
    return (struct foo *) rc;
}

The struct relaxed_foo shall be kept internal to the implementation.

Sorry I am too late. The right way is indeed to use a constructor like this:

struct foo { const int value; };
struct relaxed_foo { int value; };
struct foo * init_foo(int value) {
    struct relaxed_foo * rc = malloc(sizeof(struct foo));
    rc->value = value;
    return (struct foo *) rc;
}

The struct relaxed_foo shall be kept internal to the implementation.

and how is that real?

Let me state, as I have before, your assuming that the constant element is writable.

That's generally a safe assumption with malloc. There's no way to do what you want without subverting the type system, so drop the const qualifier, or accept the risks.

Edited 5 Years Ago by Narue: n/a

This question has already been answered. Start a new discussion instead.