3 ms·
>it very much changes the feel of the language, namely into one where you need to insert pointless casts to satisfy a whiney compiler You could use the exact s
by sjolsen 11y ago
>it very much changes the feel of the language, namely into one where you need to insert pointless casts to satisfy a whiney compiler
You could use the exact same argument against any type-safety feature: inserting "pointless" forward declarations, inserting "pointless" const qualifiers, etc., to "satisfy a whiney compiler."
The thing is, implicit conversion from void* is plainly unsound, type theoretically speaking. It has certain advantages, but is not necessary in order to have those advantages. For example, it makes use of malloc easier, but one could also make the vast majority of uses of malloc easier with something like
#define ALLOC(TYPE,N) ((TYPE*)malloc(N*sizeof(TYPE)))
Or at least, one could if C had a remotely regular type syntax and/or actual type genericity. In contrast, you actually can write
template <typename T>
T* alloc(std::size_t n) {
return static_cast <T*> (malloc (n * sizeof (T)));
}
in C++, and it's even straightforward to add additional logic like overflow detection. Mark it inline and stick it in a header, and it's effectively the same as the above ALLOC macro, except that it actually works. Now, contrast
int* array = malloc(256*sizeof(int));
with
int* array = alloc<int> (256);
The C++ expression is simpler. Now, if you change the type of the array, but forget to change the allocation expression (for whatever reason; maybe you're using the absurd convention of declaring all your variables before you start initializing and using them):
char* array = malloc(256*sizeof(int));
// vs
char* array = alloc<int> (256);
You get a type error with the C++ version, and the C version silently compiles. Not too much of an issue in this case -- you'll just waste a bunch of memory -- but go from char to int instead of int to char, and now you've got buffer overflows.
As for the argument made elsewhere in this thread that explicitly casting the result of malloc in C can mask the fact that malloc has been implicitly delcared, that's a language bug -- one that was fixed more than fifteen years ago.
- asveikau 11y agoYes, I'm glad that you can use templates to re-implement operator new [] in a way that is susceptible to integer multiplication overflows. In all seriousness though, I really mean it when I say I intellectually understand the C++ fan's response to a number of these issues. It took me a long time of writing C but I do understand the template-nerd habitat, and can acknowledge its strengths and use those tricks when working in a .cpp file. What frustrates me is to see the rigidity with which it is followed, and the failure to understand the world in a different way. There is a different world out there that doesn't mind an implicit conversion from void pointers, and they're not "wrong".
- sjolsen 11y agoMy point isn't about templates or memory allocation (hence the code that doesn't check for overflow or worry about object construction). It's that implicit casts from void* are unnecessary in C++, addressing your complaint that it's annoying not to have them. My point is that the lack of implicit casts from void* should not be frustrating, because there are in what are by far the most common use cases equally convenient ways of doing the job. >What frustrates me is to see the rigidity with which it is followed, and the failure to understand the world in a different way. There is a different world out there that doesn't mind an implicit conversion from void pointers, and they're not "wrong". I have seen and lived in the world where casts from void* are common, and where making those casts implicit is a convenience (and that world is not the world of C++). I understand that world. I understand that viewpoint. I just strongly disagree with it.
- asveikau 11y ago> It's that implicit casts from void* are unnecessary in C++ Very well aware of the C++-head's answer to these problems. > My point is that the lack of implicit casts from void* should not be frustrating, This was a discussion about whether or not C++ is a superset of C. I wrote up the difference that frustrates me the most and all other comments were missing.