3 ms·
I'm sorry, I don't understand why am being educated here, meanwhile I know how things work, both in C and C++. I literally got downvoted for contributing my opi
by pelmo 6y ago
I'm sorry, I don't understand why am being educated here, meanwhile I know how things work, both in C and C++. I literally got downvoted for contributing my opinion (not an advice) on what a person whom I replied wanted to know to better understand C++ without its complexity, because some people thought "that you shouldn't learn how to work with strings". Which is ridiculous. Now I regret doing so.
But I've read what you wrote anyway. You contradict yourself here:
>There is nothing inherently inefficient about using std::string
>it's a "zero-cost abstraction"
>You can benefit from doing it yourself
You could've asked if I don't know something that I'm talking about, I could've clarified.
> But the data structure implemented by std::string is a reasonable choice for lots of scenarios
For example, these "lots of scenarios" do not include the projects I'm working on, and for a good reason.
>most C++ compilers, are written in C++
I'm aware of self-hosting. The point that I was trying to convey is that, at some point, the "unsafe and poor C" was used in order to create that language, and further improve it.
>Expert C++ programmers know which parts of "modern" C++ have zero cost and can be used freely
And those are things that do not start with "std::"
>unnecessarily difficult to become an expert in
There's a difference between being an expert software engineer and expert in a particular programming language's architecture. First one involves understanding systems and know how to solve problems efficiently; second one doesn't require you writing complex software, rather learn from the docs and stay up to date with the new features without ever programming quality software.
- gumby 6y agoSide point: > I literally got downvoted for contributing my opinion I noticed that but my one upvote was not sufficient. Discussing upvoting / downvoting is discouraged on this site but I consider that unfortunate, as the votes (well, downvotes in particular) are part of the signal. Unfortunately they are also frequently used for "I disagree" rather than "this is off topic". I disagree with you but like every other user have the opportunity to express that by typing a response.
- comex 6y ago> I'm aware of self-hosting. The point that I was trying to convey is that, at some point, the "unsafe and poor C" was used in order to create that language, and further improve it. You wrote: > "std::string" is a container, which means using it causes unnecessary inefficiency. How do you think it was implemented? C++ was written in C, by using its functions and data types. Your wording strongly implies that the implementation of std::string is written in C, or at least that C++ is somehow layered over C in a way that explains the "unnecessary inefficiency" (which you could bypass by using C directly). The fact that the first C++ compilers, historically speaking, were written in C seems quite irrelevant. Perhaps you were trying to convey that the implementation of the C++ standard library is more C-like than typical C++, because it is lower-level and can't rely on the bits of the standard library that it's trying to implement? But that is also not what you said. > > Expert C++ programmers know which parts of "modern" C++ have zero cost and can be used freely > And those are things that do not start with "std::" If you are as much of an expert as you say, I assume you are engaging in rhetorical hyperbole.
- pelmo 6y agoThis discussion is really off-topic, but whatever, it seems like something can be possibly learned from it. >Your wording strongly implies ... that C++ is somehow layered over C Yes, I did not mean that, I should've written the next sentence on the new line to not create that confusion. >The fact that the first C++ compilers, historically speaking, were written in C seems quite irrelevant. Let me rephrase what I've meant with the std::string example. If you want to understand my perspective, you should try to think about things as they are. What is std::string really? What does it do? What happens when you use it? When do you use it? What's the purpose of it in the place where you need to use it? Now, hear me out: in majority of cases (I've read lots of codebases, majority of them are eye-bleeding), people think it's just a way to declare a string. Technically, it is. However, "string" is not a type, really. It's a container like a "vector". That means, that it has a bunch of things inside, that you can also use: could be functions, could be some other things. When you care about efficiency (and the complexity of your program), you care about what you use, and what's the final output that you get after you feed your code to the compiler. Now, majority of people assume (or don't and they just don't know about that) that C++ probably has everything right and everything is good, because there are super smart people working on it, and you should trust the compiler no matter what; and they will defend any decision that C++ authors will make. There's nothing really bad at implementing features similar to those of the "Modern C++". What matters is how they are implemented. C++, generally speaking, is inefficient by design. So, it's not that the programming language itself is horrible, but rather compilers. It's possible that someone would write a highly efficient C++ compiler that compiles 1M LOC/s and it has a "string" type, and if you want to use some additional features to do operations on them, you wouldn't need to include thousands of unnecessary lines of code to your generated program. But, today, this is not true with any C++ compiler (GNU C++, MSVC, ICC, etc.). What people seem to miss, is that it's possible to use better implementations (that are available for free!) of many C++'s standard library functions, especially for data structures and algorithms. Now, if you take the "minimalism" of C, get rid of "classes" (there are structs), and use better implementations - wouldn't that be better than what C++ STD has to suggest? Practice shows, it is. And experts know that (that's why they are experts, not because they have X years of experience at a brand-level company, but because they know what they do and it was proven in practice). How to understand my perspective? You should think about memory. And the code that your compiler produces. Now, apply the memory layout to your generated program and see what's going on. In most of the cases, where people happily use C++ with std::, what happens is that each call goes through a maze of branching. And what I'm trying to say is that that branching is unnecessary. Why would I use something like that, when I can not use it and perfectly do my job without any pain that people talk about all the time? All in all, the reasons to not use these things are performance. You may not be in an agreement with me, because you may be one of the folks who are from the "solving problems without caring about efficiency" camp. And let me actually provide you with an example: Let's assume we're a beginner modern C++ programmer, who's enthusiastic about programming (so it's most likely that I will use Visual Studio with MSVC!). And we also want to use std::string. So, let's do that! #include <iostream> int main() { std::string str = "hello"; std::cout << str << std::endl; } The code above looks pretty much simple, we just ask the compiler to output "hello". Nothing seems suspicious about that. Now, let's step into our code and see where it goes for just std::string (ignoring ::cout and ::endl): basic_string(...) constexpr explicit _Compressed_pair(...) constexpr allocator() noexcept {} constexpr explicit _Compressed_pair(...) _String_val() noexcept : _Bx(), _Mysize(0), _Myres(0) {} _Container_base12() noexcept : _Myproxy(nullptr) {} _String_val() noexcept : _Bx(), _Mysize(0), _Myres(0) {} _Bxty() noexcept {} _String_val() noexcept : _Bx(), _Mysize(0), _Myres(0) {} constexpr explicit _Compressed_pair(...) basic_string(...) _Alty& _Getal() constexpr _Ty1& _Get_first() noexcept constexpr allocator(const allocator<_Other>&) noexcept {} _Container_proxy_ptr12(_Alloc& _Al_, _Container_base12& _Mycont) _NODISCARD __declspec(allocator) _Ty\* allocate(_CRT_GUARDOVERFLOW const size_t _Count) _NODISCARD constexpr size_t _Get_size_of_n(const size_t _Count) __declspec(allocator) void\* _Allocate(const size_t _Bytes) __declspec(allocator) static void\* _Allocate(const size_t _Bytes) _NODISCARD constexpr _Ty\* _Unfancy(_Ty\* _Ptr) noexcept _NODISCARD constexpr _Ty\* addressof(_Ty& _Val) noexcept void _Construct_in_place(... _NODISCARD constexpr _Ty\* addressof(_Ty& _Val) _NODISCARD void\* _Voidify_iter(_Iter _It) noexcept void _Tidy_init() noexcept static _CONSTEXPR17 void assign(_Elem& _Left, const _Elem& _Right) noexcept basic_string& assign(_In_z_ const _Elem\* const _Ptr) _NODISCARD static _CONSTEXPR17 size_t length(_In_z_ const _Elem\* const _First) basic_string& assign(_In_reads_(_Count) const _Elem\* const _Ptr, _CRT_GUARDOVERFLOW const size_type _Count) value_type\* _Myptr() noexcept bool _Large_string_engaged() const noexcept _CSTD memmove(_First1, _First2, _Count \* sizeof(_Elem)); static _CONSTEXPR17 void assign(_Elem& _Left, const _Elem& _Right) noexcept void _Release() noexcept ~_Container_proxy_ptr12() And those are all functions. What if we were to use "const char*" instead, if our intentions were to just output a simple string? Nothing. It would not travel to any library, because it's not a library implementation. And if I were to make my own string handler, it wouldn't be as messy. Ah, the resulting code with "std::string" is 60KB (that's bonkers!), meanwhile with "const char*" it's 40KB (still bonkers!). > the implementation of the C++ standard library is more C-like than typical C++ Yes, I did not say that, and I did not think about that. >as much of an expert as you say I never said that I'm an expert, though!