3 ms·
In my opinion, this is an important issue and not "bikeshedding", but it can be discussed whether the term "C/C++" is always an example of that idea or not. I
by 1718627440 1y ago
In my opinion, this is an important issue and not "bikeshedding", but it can be discussed whether the term "C/C++" is always an example of that idea or not. I think it is not, but it is connected enough, that I won't use it to side step the issues.
- pjmlp 1y agoSo there will be zero C language constructs, and C standard library functions being called, on your C++ source code?
- 1718627440 1y agoI mostly write C, but yes even a simple call to e.g. malloc has different semantics in C++ (you need to cast).
- pjmlp 1y agoProper C++ should use new, delete, custom allocators, and standard collection types. Even better, all heap allocations should be done via ownership types. Calling into malloc () is writing C in C++, and should only be used for backwards compatibility with existing C code. Additionally there is no requirement on the C++ standard that new and delete call into malloc()/free(), that is usually done as a matter of convenience, as all C++ compilers are also C compilers.
- deleted 1y ago[deleted]
- 1718627440 1y ago> Calling into malloc () is writing C in C++, and should only be used for backwards compatibility And this is exactly the stance I am arguing against. C++ is not the newer version of C. It forked of at some point and is a quite different language now. One of the reasons I do use malloc for, is for compatibility with C. It is not for backward compatibility, because the C code is newer. In fact I actively change the code, when it needs a rewrite anyway, from C++ to C. The other reason for using it even when writing C++ is, that new alone doesn't allow to allocate without also calling the constructor. For that I call malloc first and then invoke the constructor with placement new. For deallocating I call the destructor and then free. This also has the additional benefit, that your constructor and deconstructor implementation can fail and you can roll it back.
- pjmlp 1y agoSo it would fail to compile when configuring static analysis to build on error when using C with C++ compiler. Finally, people like to argue between C and C++ when it convenient to do so, yet the compiler language switches to use C extensions in C++ mode keep being used across many projects.
- 1718627440 1y ago> So it would fail to compile when configuring static analysis to build on error when using C with C++ compiler. What do you mean? I don't think I can follow you. > yet the compiler language switches to use C extensions in C++ mode keep being used across many projects. When you use compiler extensions, that just happen to be both available in C and C++, I wouldn't say you are writing C in C++, I mean the extension isn't standard C either. Code written in C++ has different semantics, even when it is word-for-word the same as C code. They ARE different languages.
- pjmlp 1y agoOnly when removing everything that C++ adopts from C, other than low level implementation details that cannot be done in any other way. That is what writing proper modern C++ is all about, anything else is writing C in C++. Null terminated strings with pointer arithmetic instead of std::string and string_view, pointer arithmetic instead of std::span, bare pointer arrays instead of std::array and std::vector, C style casts,....
- 1718627440 1y ago> That is what writing proper modern C++ is all about, anything else is writing C in C++. That is a claim that is yours and I do not agree with that. C++ that does not fit your taste of modern C++ does not suddenly become C, it is likely a syntax error in C and when it compiles it has a different meaning. Code that may look to you like C in C++ has C++ semantics, that differs from C semantics.
- jb1991 1y ago
- bnolsen 1y agoCustom allocators in c++ was never enjoyable nor easy. It introduces more template slop everywhere. That's one thing I really liked about eastl, it did allocators much better. But it wasn't maintained.
- 1718627440 1y agoI don't use templates for that at all. Instead of: Class * object = new (...); I do: Class * object; object = malloc (sizeof Class); if (nullptr == object) // ... error handling new (object) Class (...); or if the constructor needs to fail: Class * object; object = malloc (sizeof Class); if (nullptr == object) // ... error handling new (object) Class (); if (!Class::init (object, ...)) { object->~Class (); free (object); // ... other error handling }