• Java is utter shit
    97 replies, posted
[quote] On boost, he's talking about C++, not a bundle of (useful, but that's not the point) external libraries which tack on even more features to an already bloated language. (the last bit there is my own feeling on the matter) [/quote] Boost will be and already is (in parts) part of C++. And did you just call C++ bloated? o_O [quote] [url]http://yosefk.com/c++fqa/defective.html[/url] read the summary.[/QUOTE] [quote] You may think it's a StringToStringMap, but only until the tools enlighten you - it's actually more of a... [code] // don't read this, it's impossible. just count the lines std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > [/code] [/quote] First of all, that is a map of string keys and string values. The std::less is the comparator and you don't need to worry about it. Any proficient programmer should be able to figure this out. That said, the compiler [i]really doesn't[/i] spit out information as stupid and horrid as he says. For example: [cpp] typedef std::map<std::string, std::string> StringToStringMap; int main() { StringToStringMap m; const StringToStringMap &mr = m; StringToStringMap::iterator i = mr.begin(); } [/cpp] [quote] main.cpp(12) : error C2440: 'initializing' : cannot convert from 'std::_Tree<_Traits>::const_iterator' to 'std::_Tree<_Traits>::iterator' [/quote] That's not exactly hard to read and understand. At all. A lot of his arguments don't really make sense with professional tools like MSVC and VAX, proper usage of the SC++L and boost, etc. He keeps talking about how C++ doesn't do garbage collection and basically refuses to hold your hand everywhere - but C++ is low level language, it's not supposed to hold your hand. That's the whole point of point low level. If he wants garbage collection and reflection and all that good stuff, he should use C# and stop attacking C++. I'd much rather use C# than Java. Stop attacking me with "you're so childish" when you don't understand my argument.
You obviously have not read the summary, at all. I'll quote for you. "This page summarizes the major defects of the C++ programming language (listing all minor quirks would take eternity). To be fair, some of the items by themselves could be design choices, not bugs. For example, a programming language doesn't have to provide garbage collection. It's the combination of the things that makes them all problematic. For example, the lack of garbage collection makes C++ exceptions and operator overloading inherently defective. Therefore, the problems are not listed in the order of "importance" (which is subjective anyway - different people are hit the hardest by different problems). Instead, most defects are followed by one of their complementary defects, so that when a defect causes a problem, the next defect in the list makes it worse." I find C++ potentially obsoleted continually. D for example, provides all the features of C++ and makes them sane, making it a very powerful language indeed. (that is if we ignore the major problems surrounding it currently like two standard libraries(boost, stl, lol), crappy documentation(lol most c++ tutorials and most books), and a bad compiler(lol incompatible c++ compilers)). Back to C#, I don't believe there's a place for it in the world. Hacky in-between languages end up nasty. Like C++, half way between high and low level and doesn't do either excellently. The jack of all trades is a master of none.
Wow that statement about exceptions and garbage collection is stupid. Also you are saying C++ is shitty due to coders not C++ itself, lawl.
[QUOTE=nullsquared;18424416]And I'd love for you to come up with a counter argument to my every point. Go ahead.[/QUOTE] Why? I just said that it would only generate pages of argumentation because a lot of them are matter of opinions. I gave you operator overloading as an example. Of course, you'll say some of them are facts (for instance, primitives not deriving from object), and you would be right, but we could still argue for pages about whether that's a good thing or not. And I'm not going to keep arguing with someone who believes that the 22 sections of that website are dedicated to garbage collection. The bottom paragraph of the StringToMap or whatever example shows a fundamentally broken aspect of C++ (the fact that you can't pass a std::vector<char*> to a function expecting a std::vector<const char*>). [QUOTE=high;18427404]Wow that statement about exceptions and garbage collection is stupid.[/QUOTE] Do you have something to say? What is stupid about it? Have you read the relevant examples he gives about it? All I hear is "hurr durr he's dum" but no reason why.
[QUOTE=gparent;18427471]Why? I just said that it would only generate pages of argumentation because a lot of them are matter of opinions. I gave you operator overloading as an example. [/quote] Why? Because I want to hear how I'm wrong. Operator overloading is a poor example. Look at my RK4 code example. [quote] And I'm not going to keep arguing with someone who believes that the 22 sections of that website are dedicated to garbage collection. [/quote] They are. Most of his answers tie in garbage collections one way or another. [quote]The bottom paragraph of the StringToMap or whatever example shows a fundamentally broken aspect of C++ (the fact that you can't pass a std::vector<char*> to a function expecting a std::vector<const char*>)[/QUOTE] I don't understand why you'd want to do that, those two vectors are essentially different types. [editline]06:43PM[/editline] [QUOTE=blankthemuffin;18427338]For example, the lack of garbage collection makes C++ exceptions and operator overloading inherently defective. [/quote] Yeah, lets talk about this. His argument is essentially "without garbage collection, operator overloading creates too many copies, which is slower than just having garbage collection in the first place." (not going to look for the quote, but I remember that's what he said) Ok, so, garbage collected operator (pseudo code): [cpp] Vector operator +(Vector a, Vector b) // 0 copies due to references { return new Vector(a.x + b.x, a.y + b.y, a.z + b.z); // 1 copy, heap allocated } Vector result = x + y; // 0 copies due to references // 1 copy total, heap allocated [/cpp] Ok, non-garbage collected operator (pseudo code): [cpp] Vector operator +(const Vector &a, const Vector &b) // 0 copies due to references { return Vector(a.x + b.x, a.y + b.y, a.z + b.z); // 1 copy, stack allocated } Vector result = x + y; // 0 copies given an optimizing compiler (MSVC/GCC) // 1 copy total, stack-allocated [/cpp] I fail to see his argument of too many copies. Even if x + y warrants an extra copy due to poor optimization, that's 2 stack copies vs 1 heap copy. Stack memory allocation is MUCH faster than heap memory allocation - especially if this heap is managed by a garbage collector. [quote](that is if we ignore the major problems surrounding it currently like two standard libraries(boost, stl, lol), crappy documentation(lol most c++ tutorials and most books), and a bad compiler(lol incompatible c++ compilers)). [/QUOTE] Wait, what? Boost is not a standard library, it's part of the standard library (or will be, at least). STL is not a standard library, either...? C++ itself has near-perfect documentation... did you really just judge a language based on crappy online tutorials? Bad compiler, what? Never used MSVC or a recent GCC?
You really missed the point there, which is probably understandable if you havn't played with D. Those are all issues D suffers from, but with some stretching I've come to realise that C++ suffers to a lesser extent the same issues. We should save this for a C++ is utter shit thread.
[QUOTE=nullsquared;18427615]Why? Because I want to hear how I'm wrong. Operator overloading is a poor example. Look at my RK4 code example.[/QUOTE] I looked at it, I even answered it. I don't think it's a big deal, and not having operator overloading avoids all of the problems you could potentially have with it. It's not just a feature they didn't code because they didn't feel like it, it's by design from what I understand. [QUOTE=nullsquared;18427615]I don't understand why you'd want to do that, those two vectors are essentially different types.[/QUOTE] The only difference is const. You can pass a non-const int to a function expecting a const int, but you can't pass a vector containing const objects to a function expection a vector that contains non-const object. Makes no sense. I'm not asking that you should be able to pass a vector containing ints to a function that explains a long long vector (implicit template parameter casting), but const shouldn't make the code fail to compile in the case above (if C++ was sane).
[QUOTE=gparent;18422161]The standard body could define a standard way to do name mangling, but they don't. It makes it a lot more difficult when things aren't defined.[/QUOTE] Name mangling isn't part of the language, it's part of the [url=http://en.wikipedia.org/wiki/Application_binary_interface]ABI[/url], together with platform-specific things like structure alignment and layout, register usage, and function calling conventions. Interoperability between different compilers depends on all those things, not just name mangling. And compiler vendors do, I believe, work together to create de-facto standard ABIs for the platforms they target. [QUOTE=nullsquared;18427615]I don't understand why you'd want to do that, those two vectors (std::vector<char*> and std::vector<const char*>) are essentially different types.[/QUOTE] They're different types as far as C++ is concerned, but the conversion is semantically valid: There's nothing you can do to a std::vector<const char*> that wouldn't be OK to do to a std::vector<char*>. It wouldn't be unreasonable for a programming language to allow this conversion. [QUOTE=nullsquared;18427615]Stack memory allocation is MUCH faster than heap memory allocation - especially if this heap is managed by a garbage collector.[/QUOTE] Keep in mind that std::vector [i]does[/i] use heap allocation. It has to, in order to be able to resize itself dynamically. The object on the stack contains a pointer to a heap-allocated array, together with other things like the array's current size. One of the new features in the upcoming new version of C++ is [url= http://www.artima.com/cppsource/rvalue.html]rvalue references[/url], which provide a way to avoid unnecessary copying of heap-allocated data in situations like returning a std::vector from a function. [QUOTE=nullsquared;18427615]STL is not a standard library, either...?[/QUOTE] The STL was a de-facto standard that predated the actual ISO standardization of C++, but most of it was incorporated into the C++ standard library with only slight changes. These days, "STL" generally refers to those portions of the C++ standard library, not the original library written by SGI.
[QUOTE=Wyzard;18432021]Name mangling isn't part of the language, it's part of the [url=http://en.wikipedia.org/wiki/Application_binary_interface]ABI[/url],[/QUOTE] Ah, I see.
[QUOTE=Wyzard;18432021]They're different types as far as C++ is concerned, but the conversion is semantically valid: There's nothing you can do to a std::vector<const char*> that wouldn't be OK to do to a std::vector<char*>. It wouldn't be unreasonable for a programming language to allow this conversion.[/QUOTE] reinterpret_cast ftw! std::vector<const char> lol; lol.push_back('a'); std::vector<char> lol2 = *((std::vector<char>*)&lol); Edit: O NO! Linux fanboys be rating me dumb! Blank, I love you, but not enough to unignore you.
[QUOTE=gparent;18431934]I don't think it's a big deal[/quote] Um... [cpp] Vec2 dp = Vec2.mul( // a + Vec2.add(a.pos, Vec2.add( // (b + c) * 2 + d Vec2.mul(Vec2.add(b.pos, c.pos), 2), d.pos) // * 1/6 ), 1.0 / 6.0); [/cpp] vs. [cpp] Vec2 dp = (a + 2 * (b + c) + d) / 6.0; [/cpp] If you're doing any moderate math at all, operator overloading really helps. [quote]and not having operator overloading avoids all of the problems you could potentially have with it.[/quote] Once again, hand holding. Just because operating overloading can be abused by the programmer, doesn't mean it's a bad thing itself. [quote] The only difference is const. You can pass a non-const int to a function expecting a const int, but you can't pass a vector containing const objects to a function expection a vector that contains non-const object. Makes no sense. [/quote] No, it makes perfect logical sense. If std::vector<long long> is different from std::vector<int>, I see no reason std::vector<const int*> shouldn't be different from std::vector<int*>. It keeps the language consistent. [quote] Keep in mind that std::vector [i]does[/i] use heap allocation. It has to, in order to be able to resize itself dynamically. The object on the stack contains a pointer to a heap-allocated array, together with other things like the array's current size. [/quote] It was an example of 3D vectors, not the std::vector container. Either way, keeping track of your own array's capacity and size is still more effective than letting a garbage collector do it for you. And guess what, you don't even have to do it yourself since RAII does it for you. [quote] The STL was a de-facto standard that predated the actual ISO standardization of C++, but most of it was incorporated into the C++ standard library with only slight changes. These days, "STL" generally refers to those portions of the C++ standard library, not the original library written by SGI. [/quote] Um, therefore, my comment "STL is not a standard library." ...
[QUOTE=nullsquared;18435373]If you're doing any moderate math at all, operator overloading really helps.[/quote] Right. Once again, opinion. Maybe you think it's necessary, I don't. [QUOTE=nullsquared;18435373]Once again, hand holding. Just because operating overloading can be abused by the programmer, doesn't mean it's a bad thing itself.[/quote] I never said it was. Once again, opinion; I don't think the benefits are worth the potential problems. I don't think it's a bad thing that C++ has it either, though. [QUOTE=nullsquared;18435373]No, it makes perfect logical sense.[/quote] No, it doesn't. It makes logical sense in the context of C++ and how templates work, but it doesn't make logical sense to someone who isn't experienced with C++, or someone who expects sane const behavior coming from another language. If you ask someone "If you request from me something that you won't modify, and I give you something and tell you "You're free to do whatever you want with this", would you deny the request?" they'll probably answer no if they aren't complete morons. It doesn't make sense that I can pass an int to a function expecting a const int, but I can't pass a vector containing ints to a function expecting a vector of const int. They're both logically the same in that context - the function just won't modify the contents of the vector even if it could, but templates are changing that behavior and making something that should work, not work. You can deny this all you want, but there is no logic in denying someone the ability to pass a non-const thing to something that guarantees it won't modify the parameter. The only sense it has is that templates are instantiated once per different template arguments and that there is no implicit casting of const to non-const.
gparent do you even program?
[cpp]std::vector<int*> a; some_func(a); [...] void some_func(std::vector<const int*> &vec) { const int *a = new int(5); vec.push_back(a); }[/cpp] Though you push a constant integer in there, it may be modified after the function returns. That is, I think, why you can't cast from std::vector<T> to std::vector<const T>.
[QUOTE=gparent;18440574]there is no implicit casting of const to non-const.[/QUOTE] Which is, once again, logical. A list of Foo is not the same as a list of const Foo. Understanding that is part of learning C++. You can ask someone something in plain English and then compare it to programming for endless amounts of things. [editline]04:32PM[/editline] [QUOTE=gparent;18440574]Maybe you think it's necessary, I don't.[/QUOTE] Are you freaking blind?! :bang: My example is very clear, how can you say that the operator-overloading version is not better than the non-operator-overloading version??
Your example is very contrived. The answer is very clear also, overloading can hide errors. Both when you somehow get an error state, and also when you have retarded messes like your example and ambiguous results. Say those were Vector3's, your * overload, is that dot or cross product? There is nothing wrong with the C way unless you want to make up some seriously contrived examples, and there can be a lot wrong with overloading. If the answer in plain English is completely different to the answer in your language of choice, that language fails to be intuitive. This is a major issue, I don't want to be going to reference books every 5 seconds to find the "right way" of doing things, and a lot of the time one might not even twig that there is an issue since the most blatantly obvious sane way seems to work fine. Especially when texts often conflict with each other in their choices of right and wrong.
[QUOTE=blankthemuffin;18441432]Both when you somehow get an error state,[/quote] Things that can get into an erroneous state are not to be operator overloaded. [quote]and also when you have retarded messes like your example and ambiguous results. Say those were Vector3's, your * overload, is that dot or cross product?[/quote] Neither, it would be the same thing as multiplying floats, just vectorized. dot and cross would be ... well, dot() and cross(). Just like shaders.
[QUOTE=nullsquared;18441083]A list of Foo is not the same as a list of const Foo. Understanding that is part of learning C++.[/QUOTE] No shit I even explained in my post that I knew why it was broken that way. [QUOTE=nullsquared;18441083]You can ask someone something in plain English and then compare it to programming for endless amounts of things.[/QUOTE] Irrelevant. In my example, it is perfectly fine. There is no logical reason whatsoever why I can't pass a non-const container to a function expecting a const one. All that const says is "You won't modify this". I'm passing a container that can be modified. It meets the requirement, and it should work, period. Just like it does for functions. Whether you have a stubborn love for C++ or not. [QUOTE=nullsquared;18441083]Are you freaking blind?! :bang: My example is very clear, how can you say that the operator-overloading version is not better than the non-operator-overloading version??[/QUOTE] No, you're blind. I explained clearly why in the previous post. But I'll say the part you want to hear - Yes, the operator overloaded version requires a few seconds less to read. [QUOTE=high;18440838]gparent do you even program?[/QUOTE] I don't get the point of your question. My example made sense, even if it's an analogy. Was that it? [QUOTE=ZeekyHBomb;18441067]Though you push a constant integer in there, it may be modified after the function returns.[/QUOTE] Which is fine. The only thing you shouldn't be able to do is modify the elements inside the vector that was passed (which is what std::vector<const T> implies). What happens outside the function is irrelevant.
[QUOTE=gparent;18443882]Irrelevant. In my example, it is perfectly fine. There is no logical reason whatsoever why I can't pass a non-const container to a function expecting a const one. All that const says is "You won't modify this". I'm passing a container that can be modified. It meets the requirement, and it should work, period. Just like it does for functions. Whether you have a stubborn love for C++ or not.[/QUOTE] Apparently you missed zeeky's post. [QUOTE=ZeekyHBomb;18441067][cpp]std::vector<int*> a; some_func(a); [...] void some_func(std::vector<const int*> &vec) { const int *a = new int(5); vec.push_back(a); }[/cpp] Though you push a constant integer in there, it may be modified after the function returns. That is, I think, why you can't cast from std::vector<T> to std::vector<const T>.[/QUOTE] And either way, you can still reinterpret_cast if you must cast between the 2.
[QUOTE=ZeekyHBomb;18441067][cpp]std::vector<int*> a; some_func(a); [...] void some_func(std::vector<const int*> &vec) { const int *a = new int(5); vec.push_back(a); }[/cpp] Though you push a constant integer in there, it may be modified after the function returns. That is, I think, why you can't cast from std::vector<T> to std::vector<const T>.[/QUOTE] This is another form of the [url=http://www.parashift.com/c++-faq-lite/proper-inheritance.html#faq-21.3]container-of-Base vs. container-of-Derived[/url] problem. I'd thought that might be related to this, but for some reason I couldn't think of an example to confirm it to myself. You just did, and you're absolutely right: C++ is [b]correct[/b] in rejecting this code. I take back what I said earlier about the conversion being semantically valid. Be careful about talking about a std::vector<const T>, though. If T is a pointer, "const T" means a const pointer to a non-const integer, not a non-const pointer to a const integer. In a std::vector<const int*>, the integers are const (which is why the above problem applies), but the actual pointers stored in the vector are not. If they were (e.g. std::vector<const int* const>), you wouldn't be able to add anything to the vector, because the internal assignment statements in the vector's implementation would be forbidden. A std::vector<const T> isn't very useful, for that reason.
Also, access violations ftw! [cpp]#include <Windows.h> #include <vector> #include <map> #include <string> void Fuck(std::vector<const char*>& test) { test.push_back("test"); } int main(int argc, char* argv[]) { std::vector<char*> test; Fuck(*((std::vector<const char*>*)&test)); test[0][0] = 'a'; //"test" is in a read only memory section so this will throw an access violation exception. return 0; } [/cpp]
The use of read-only memory sections is actually implementation-dependent, but what's your point? You're doing an unsafe cast to an incompatible type and getting undefined behavior as a result.
I am agreeing with you guys, showing the faults of it :P.
[QUOTE=gparent;18443882]Yes, the operator overloaded version requires a few seconds less to read.[/quote] Any many more to write. Not counting all the many to debug, in case you accidentally put the parameters in the wrong order or something of the sort (as I did several times and had a hard time figure out WTF was going on with the math). I don't get the point of your question. My example made sense, even if it's an analogy. Was that it?
[QUOTE=nullsquared;18445590]Any many more to write. Not counting all the many to debug, in case you accidentally put the parameters in the wrong order or something of the sort (as I did several times and had a hard time figure out WTF was going on with the math).[/quote] Maybe it's you then. I don't find it particularly hard to separate the terms and add the operations up separately. It's more of a hassle, but I already agreed with that. [QUOTE=nullsquared;18445590]I don't get the point of your question.[/quote] High tried to make a joke or something and I didn't get it. Wasn't aimed at you.
[QUOTE=gparent;18447292] High tried to make a joke or something and I didn't get it. Wasn't aimed at you.[/QUOTE] Woops. I didn't write that (accidentally fell out of quote tags), so when I just read it I was like WTF, I didn't write that :v:
Next year, when i start programing, I have to take java in order to take C++, damn it.:frown:
Java may suck to use but learning it will not kill you.
Java is so slow
[QUOTE=Intoxicated Spy;18447742]Next year, when i start programing, I have to take java in order to take C++, damn it.:frown:[/QUOTE] Won't hurt. You can still learn C++ in your free time you know..
Sorry, you need to Log In to post a reply to this thread.