cstructconstantsundefined-behaviorbus-error

How are constant struct members handled in C?


Is it OK do do something like this?

struct MyStruct {
    int x;
    const char y; // notice the const
    unsigned short z;
};
struct MyStruct AStruct;
fread(&MyStruct, sizeof (MyStruct), 1,
      SomeFileThatWasDefinedEarlierButIsntIncludedInThisCodeSnippet);

I am changing the constant struct member by writing to the entire struct from a file. How is that supposed to be handled? Is this undefined behavior, to write to a non-constant struct, if one or more of the struct members is constant? If so, what is the accepted practice to handle constant struct members?


Solution

  • It's undefined behavior.

    The C11 draft n1570 says:

    6.7.3 Type qualifiers

    ...

    ...

    If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.

    My interpretation of this is: To be compliant with the standard, you are only allowed to set the value of the const member during object creation (aka initialization) like:

    struct MyStruct AStruct = {1, 'a', 2};  // Fine
    

    Doing

    AStruct.y = 'b';   // Error
    

    should give a compiler error.

    You can trick the compiler with code like:

    memcpy(&AStruct, &AnotherStruct, sizeof AStruct);
    

    It will probably work fine on most systems but it's still undefined behavior according to the C11 standard.

    Also see memcpy with destination pointer to const data