Hi, On 2019-06-25 17:25:12 -0400, Tom Lane wrote: > Andres Freund <and...@anarazel.de> writes: > > On 2019-06-25 16:15:17 -0400, Tom Lane wrote: > >> One too many "consts" there. Pointer to const object seems fine. > >> The other part is either meaningless or will cause problems. > > > Yea - I was thinking of the pointer in RelationData, where having it as > > const *Routine const; would make sense (but it's annoying to do without > > invoking technically undefined behaviour, doing ugly things with memcpy > > or duplicating struct definitions). > > Yeah, I think trying to make such pointer fields "const", within > structures that are otherwise not const, is just more trouble than it's > worth. To start with, how will you assign the handler's output pointer > to such a field?
Yea, it's annoying. C++ is slightly cleaner in this case, but it's still not great. In most cases it's perfectly legal to cast the const away (that's always legal) *and* write through that. The standard's requirement is quite minimal - C99's 6.7.3 5) says: 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. ... Which, in my reading, appears to mean that in the case of dynamically allocated memory, the underlying memory can just be initialized ignoring the constness. At least before the object is used via the struct, but I'm not sure that strictly speaking matters. In the case of relcache it's a bit more complicated, because we copy over existing entries - but we don't ever actually change the constant fields, even though they're part of a memcpy.... Greetings, Andres Freund