The constness of gsl_vector interfaces makes no sense. This is a simple observation, but it seems to have escaped discussion for over a decade. Consider the following code (file attached). #include void notwhatyouthink(const gsl_vector * v) { v->data[0] = 42.0; } int main() { gsl_vector * v = gsl_vector_calloc(32); printf("%g\n", v->data[0]); notwhatyouthink(v); printf("%g\n", v->data[0]); gsl_vector_free(v); return 0; } Obviously, the constness of the vector is not the same as the constness of the data. But the interface leads you to believe the function is safe. Every function in GSL which takes a (gsl_vector *) argument is declared in precisely this way, either with or without the 'const', depending on the obvious intent. But the compiler knows nothing about the obvious intent, so it has no objection to the example code, which is obviously not good. This is a rookie error. I don't know how it happened. But things like this force me to question my own sanity. Was it intended to be this way? I don't think so. Am I missing something about the overall design which explains why it is this way? Probably not. The "view" objects do the more correct thing, introducing two distinct types, with designed const-correctness. You can see how the constness was an unavoidable issue there, because views are indirect by design. As I was thinking about fixes for the containers, I was trying to preserve interfaces as much as possible. In particular, I was trying to preserve the "gsl_vector *" and "const gsl_vector *" argument types in function prototypes. This led me to question the semantics of these interfaces as they are, which led to the above stupid observation. I then wondered what GSL interfaces for view objects look like, and discovered something interesting. No GSL interface (except the view headers themselves) uses a view object. Not one. So why do views exist? It seems that they are used by GSL implementations in lots of places. So, by construction (or historical accident, depending your emphasis), the views are essentially an implementation detail. Yet they are structured as if they are for client use. Very odd. It seems like the whole thing is standing on its head. The views should be the main client interface. GSL interfaces should be written in terms of views and should have true const-correctness. The memory management inherent in the container objects (as distinct from the views) should be properly factored out. The const-incorrectness of the "gsl_vector *" interfaces is just one important symptom of this deep disease. The question: What to do? There are several options, none very enticing. 1) Punt on const-correctness and the other issues with the current design. Try to wrap the oozing wounds in some bandages and forget about it. 2) Completely re-design the guts of containers while preserving the current interfaces. This can be done, in such a way as to bring views to the forefront and rationalize the design. But it punts on the interface issues, including the constness problem. 3) Re-design the guts of the containers and change all the GSL interfaces to conform to a rationalized and const-correct container architecture. This would change everything in the world that ever touches a GSL container. It also implies a near doubling of interfaces, if we follow the lead of the current view design. Doubling the interfaces just because some objects have a 'const' keyword somewhere is really disgusting. 4) Find some magic way to implement choice (3) without a need to double the interfaces. Try to get more value semantics (rather than the current pointer semantics) into the picture. Views currently have a value semantic; they live on the stack. Vectors should really be views, and should have similar semantics. You can mix and match the various ideas to create other approaches beyond these four. I have spent a lot of time looking for C container library designs that were relevant for numerical containers and solved some or all of these problems in some way. I have found none. There are lots of container libraries, like the glib containers, etc. But these are just irrelevant for GSL. Trust me, if you don't want to look for yourself. Yet, I feel that there are solutions for these problems. They may involve some casting tricks, but I don't think there has to any compromise of safety. There will, however, have to be some compromises. The goals: - const-correctness - no "doubling" of interfaces - an architecture where views are central - memory management factored out (allocation/deallocation) Ideas? -- G. Jungman