|
|
Josh @ Dreamland
|
|
Reply #32 Posted on: June 04, 2010, 12:58:43 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
"Is this a fallacy? Not any more than your arguments, so you can't complain." That final clause itself was a fallacy. You're both spouting little but fallacies.
"know what is a pointer and what is not, and that is impossible in C++." I'm going to assume you meant something other than how that reads; otherwise, that's the biggest lout of bullshit I've ever heard.
Anyway, C++ is not meant to be a garbage collected language. It implements something wonderful over C in the direction of memory management, being constructors and destructors. Google V8 is one to really whore that system. In an ExecuteString wrapper, I can say so little as { v8::HandleScope handle_scope; // Constructor allocates and integrates a new scope ExecuteString(String::New(line), "(shell)", true, true); //Operates in the newly constructed scope return 0; } // Destructor automatically disposes the new scope People get used to strings; I myself have become spoiled by them, and feel so every time I use them. C gave no way of returning new strings, save allocating them yourself. With C++, std::string is a great example of how the annoying bits are handled for you. String keeps its own reference count at the beginning of the char* in memory. When you return a string in C++, the constructor of the new string increments that count, the destructor of the old string then decrements it, and a string is returned with no manual allocation.
I had a leak once, and I used ctors and dtors to keep my own count, and to help me isolate where they were allocated that they weren't being freed. It was greatly convenient; had I wanted, I could have turned it into a garbage collector on my own. Thing is, I prefer the program to be geared correctly to take care of such itself.
Is it possible to get C++ to wipe all the memory management ickiness off your ass for you? No. What I think Rusky was trying to convey is that C++ introduces no system of reference tracking. Personally, all considered, I prefer it that way.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
luiscubal
|
|
Reply #33 Posted on: June 04, 2010, 01:43:17 pm |
|
|
Joined: Jun 2009
Posts: 452
|
know what is a pointer and what is not, and that is impossible in C++. You disagree with this, Josh? Tell me, how many variables are pointing to 0x043030FE in your program. You can't ever be sure in C++. In Java, you can. So you're left with few options: 1. You use something like Pointer<T> instead of T*. It's ugly, you still need to figure out circular references(which somehow means you need the stack trace too, yet another problem C++ makes hard to solve). You can of course just have a simple reference counter and somehow hope nobody messes around with it. Possible and I've used this method before. Still, templates mean worse compile times, harder-to-read code, and it's still unable to deal with cyclic references. 2. You iterate through the whole memory and build a conservative memory collector. Less painful to handle since you can use ordinary pointers, but it's still vulnerable to circular references and it can't be sure whether something is a pointer or something else. Say, if an integer has value 0x043030FE for some unrelated reason, a leak occurs. 3. You use macros or something else to register the stack. void myfunction(StackPosition& pos) { pos.push();
Pointer<int> p(pos, new int(5));
pos.pop(); //p is released here }
that plus several more tricks could possibly solve, but it's simply pain ugly and makes code readability worse. 4. You use something like a C++ preprocessor to automatically generate solution 3 in a pretty way. At this point, you can barely call it C++. Destructors are useful, and garbage collectors could be built to take advantage of them. However, while destructors can simplify some memory management, they aren't enough by themselves to replace GCs. People get used to strings; I myself have become spoiled by them, and feel so every time I use them. C gave no way of returning new strings, save allocating them yourself. With C++, std::string is a great example of how the annoying bits are handled for you. String keeps its own reference count at the beginning of the char* in memory. When you return a string in C++, the constructor of the new string increments that count, the destructor of the old string then decrements it, and a string is returned with no manual allocation. Shame on them. They dared to automatically dispose of strings in C++? BUT THAT'S SO INEFFICIENT!!! That aside, strings in C++ are often much better than const char*s, for similar reasons that GCs are often much better than manual memory freeing system. Is it possible to get C++ to wipe all the memory management ickiness off your ass for you? No. Therefore, when it comes to wiping out the memory management ickiness, other languages are better. Personally, all considered, I prefer it that way. For some use-cases, that indeed is the best way. For most applications, memory management is not the problem we're trying to solve. We're trying to render a document, to figure out what 3D position the 2D mouse click refers to in the computer game or what GM version the read file refers to. In those cases, memory management is an obstacle. Either way, regarding bloatness, a quote from one of Go's designers: it wasn't enough to just add features to existing programming languages, because sometimes you can get more in the long run by taking things away.
|
|
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #34 Posted on: June 04, 2010, 03:04:59 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
"Tell me, how many variables are pointing to 0x043030FE in your program" "What I think Rusky was trying to convey is that C++ introduces no system of reference tracking."
"They dared to automatically dispose of strings in C++? BUT THAT'S SO INEFFICIENT!!!" How so? The idea is a garbage collector that can linearly assume you are done with it because the entire scope's life is ending. My argument was never that all convenient things are inefficient; it's if you start periodically iterating through everything to make sure nothing's just kind of waiting there that shit becomes inefficient.
"Therefore, when it comes to wiping out the memory management ickiness, other languages are better." ...Okay. For the most part, this has worked for a few large projects. You'll probably notice that the more the language does for you, the less large projects are successfully written in it. Openoffice is a shining example, in my opinion. Only a few of its aspects have been reported as being slow (the one I am thinking of is Calc, being 12x slower than Excel at something or another). I look at Haskell, and I see things like Geordi. Marvelous little toy; not ultimately very big.
Ultimately, it's a nice thing to have a low-written runtime at your disposal in a high level language; it gets you the speed of the low with the simplicity of the high. The more things the low level system does for you, the better off you'll be. Like GM. Sprites and collisions are acceptable because something coded in a real (not GML) language handles them. Java has a few aspects of it that are "faster than C"... usually large libraries such as compression that are written in a lower level language.
If you want anything sizable that runs fast, you'll need something lower level at some point, even on our constantly improving hardware. Haven't heard anything on Singularity. But I know that the more Microsoft develops, the slower their output becomes. It is nice to swim in the high level end and have simpler-to-read code with the ugly parts handled. Microsoft's been trying that for a long time. It isn't always an option. C++ is always an option.
Maybe some day, Microsoft will fix that. C++ being an option, I mean. In the meantime, it's a true dilemma between whether you want your time to be consumed in development by your team or in execution by all users. And since programmers get paid by the hour, not by the output...
Either way, the majority of these posts is fluff. Every language has its purposes; I wouldn't want Geordi written in anything other than Haskell, because Haskell got the job done far faster and probably far more cleanly than C++ would have. It simply doesn't need that speed. I would kind of like OpenOffice to not be Java, because Java acts up on this machine sometimes, but whatever; it's free. I wouldn't have ENIGMA coded in any other way.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
luiscubal
|
|
Reply #35 Posted on: June 04, 2010, 03:59:16 pm |
|
|
Joined: Jun 2009
Posts: 452
|
String reference counting is a type of garbage collection. So I guess that means C++ STL does have GC. Too bad it's so limited. You'll probably notice that the more the language does for you, the less large projects are successfully written in it. Are you seriously suggesting that languages such as C# are unable to deliver? Either way, the majority of these posts is fluff. Every language has its purposes; I wouldn't want Geordi written in anything other than Haskell, because Haskell got the job done far faster and probably far more cleanly than C++ would have. It simply doesn't need that speed. Glad you will admit that. Maybe some day, Microsoft will fix that. False dichotomy. If it is efficiency you want with some minimal high-level tools, then why are efforts such as D so rare and why have they all failed to get any success? The number 1 reason C++ is so widely used is legacy. Had Excel started been developed today, would its team still pick C? If you want anything sizable that runs fast, you'll need something lower level at some point Which is why we have P/Invokes, JNIs and optimizers. Eventually, something will be written in C(the kernel, perhaps?). Heck, there are things that should really be written in C(or at least have a public C ABI), such as system libraries. However, this does not apply to applications. The "go fast or go high level" is another false dichotomy fallacy. And since programmers get paid by the hour Then you should pick the most productive tool, which is definitively not C++. I wouldn't have ENIGMA coded in any other way. Will you at least admit C++ has lots of legacy junk nobody needs anymore? Because that's what this discussion was about - the claim that C++ was bloated.
|
|
|
Logged
|
|
|
|
Rusky
|
|
Reply #36 Posted on: June 04, 2010, 05:01:25 pm |
|
|
Joined: Feb 2008
Posts: 954
|
"know what is a pointer and what is not, and that is impossible in C++." I'm going to assume you meant something other than how that reads; otherwise, that's the biggest lout of bullshit I've ever heard. From the point of view of a GC, you don't know if some word in memory is an integer or a pointer cast to an integer. If casting between pointers and integers were impossible, you could place GC roots at compile time; as it is you can't. Is it possible to get C++ to wipe all the memory management ickiness off your ass for you? No. What I think Rusky was trying to convey is that C++ introduces no system of reference tracking. Personally, all considered, I prefer it that way. Reference counting is not good enough in many cases. You can implement it yourself fairly easily in C++ anyway. How so? The idea is a garbage collector that can linearly assume you are done with it because the entire scope's life is ending. My argument was never that all convenient things are inefficient; it's if you start periodically iterating through everything to make sure nothing's just kind of waiting there that shit becomes inefficient. GC has come a long way from stop-the-world collectors. And as I've said before, it mostly just moves the processing required. Allocation in a GC system is just incrementing a pointer; in your favorite manual systems it is much more than that. ...Okay. For the most part, this has worked for a few large projects. You'll probably notice that the more the language does for you, the less large projects are successfully written in it. Openoffice is a shining example, in my opinion. Only a few of its aspects have been reported as being slow (the one I am thinking of is Calc, being 12x slower than Excel at something or another). I look at Haskell, and I see things like Geordi. Marvelous little toy; not ultimately very big. Haskell has Darcs and Yi. It has GHC and Cabal. It has Xmonad and seL4 and House. It has compilers for Perl 6, Lisp, bla bla bla look at Hackage. Do some research before making things up.
|
|
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #37 Posted on: June 04, 2010, 09:51:22 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
"Will you at least admit C++ has lots of legacy junk nobody needs anymore? Because that's what this discussion was about - the claim that C++ was bloated." Do you read what I write? "As a language, C++ is fairly bloated. That bloat doesn't really get in your way unless you are trying to parse it. The output is typically far from bloated, though there are slight amounts of overhead if you utilize more than C would give you alone." "From the point of view of a GC, you don't know if some word in memory is an integer or a pointer cast to an integer. If casting between pointers and integers were impossible, you could place GC roots at compile time; as it is you can't." From the point of view of Escherichia coli, your garbage collector is indistinguishable from a string of bits in memory. Now, when you're done raging over the bluntness of that statement, consider its implications. ISO C++ forbids void* arithmetic, it forbids implicit casts between pointers of non-inherited types, and it forbids implicit cast from pointer to integer. The question isn't of whether a separate garbage collector can be slapped on to the output of any old C++ program; that kind of thinking leads to output bloat instead of C85 language bloat that can be ignored. Also, you can't pretend that a garbage collector alleviates all allocation problems. Specialized ones, knowing the size of everything up front, can be used to alleviate allocation headaches and just increment a pointer. There's nothing a garbage collector can accomplish that manual can't if given equal thought. Garbage collection has come a long way, and it's typically not an O(N) clusterfuck anymore. That doesn't mean that they are programmed with magic that fixes all our resource problems. "Haskell has Darcs and Yi. It has GHC and Cabal. It has Xmonad and seL4 and House. It has compilers for Perl 6, Lisp, bla bla bla look at Hackage. Do some research before making things up." I don't see any of those as being exceptionally large... Looking at Xmonad, it's built off of X, which only serves to help my point. The rest are little things like RapidSVN that I kind of take for granted because really, they're just nice wrappers to what I'd otherwise be doing in a terminal. Also, I can be missing a huge, huge project made in Haskell without "making things up." I'm reporting my findings. I indicated what would "probably [be] notice[d]," based off of my findings. Quit accusing me of making things up simply because you disagree with my point. "Eventually, something will be written in C(the kernel, perhaps?). Heck, there are things that should really be written in C(or at least have a public C ABI), such as system libraries. However, this does not apply to applications." I hinted earlier at Microsoft Singularity. I'm glad you agree that there are some things that just had ought to be C. Much of Singularity is C, but the rest is C#. There are benefits to having garbage collection in some of the system resources that applications will be accessing. I think, however, you'll agree that Singularity oversteps the boundaries. If not, maybe you'll agree that integrated circuitry designed to implement a garbage collector is. (Or, hell, maybe you'll think it's a great idea, who the hell knows). I was reading about ATMs that have their own integrated garbage collector. I wanted to puke, personally. "The "go fast or go high level" is another false dichotomy fallacy." I wasn't citing that as a mathematical truth. There are a lot of brilliantly efficient high level things.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
luiscubal
|
|
Reply #39 Posted on: June 05, 2010, 07:15:19 am |
|
|
Joined: Jun 2009
Posts: 452
|
As a language, C++ is fairly bloated. That bloat doesn't really get in your way unless you are trying to parse it. The output is typically far from bloated, though there are slight amounts of overhead if you utilize more than C would give you alone. The first sentence is pretty good. The bloat doesn't usually get in the way but it exists. Also, that same bloat can get in the way of adding new features to C++. When a language has too many things in it, optimizing becomes problematic. Just look at the restrict keyword. Usually, adding features harms writing optimizers, and then you have to add yet more features to opt-out of features you don't need. "Eventually, something will be written in C(the kernel, perhaps?). Heck, there are things that should really be written in C(or at least have a public C ABI), such as system libraries. However, this does not apply to applications." Please note that in this sentence, I was specifically referring to C, not C++. C++ ABI is stupid. integrated circuitry designed to implement a garbage collector I would need to see how it was being implemented, how efficient it was, what it lacked, if it was opt-in or opt-out, etc. etc. before jumping to conclusions. Then again, different GCs often have different purposes. Some GCs are designed to be fast, others to be small, others to be simple, others are specifically designed for code locality. GCs are a fertile investigation field, and I'm not sure an integrated circuit would be the best way to implement GCs simply because GCs change and then we'd be stuck with an outdated one. Your claim is that only C++ is used for big applications for reasons such as efficiency, power, or something like that. My claim is that C++ is used for big applications because when those big applications were started there was nothing better or because they were started as C. Try opening a file. Ok. I can just add a few extra commands to Brainfuck. Say, ' to open file to write, " to open file to read, « to read from file and » to write to file. Would this somehow convince you to use Brainfuck?
|
|
|
Logged
|
|
|
|
|
Josh @ Dreamland
|
|
Reply #41 Posted on: June 05, 2010, 09:21:04 am |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
"Also, that same bloat can get in the way of adding new features to C++." Care to give an example? Lately it shouldn't appear the committees are having any trouble introducing new features to the language.
"My claim is that C++ is used for big applications because when those big applications were started there was nothing better or because they were started as C." That almost definitely applies to Excel, because otherwise, Microsoft would have taken the opportunity to advertise that srs biznez can really be accomplished in C#. And that IS part of their intention. Singularity's one screen shot was so transparently propaganda-laden it made me sick.
Loading ************C#*********** kernel of Mar 25 2008 Please direct your attention to the C# in the last message Did you notice the kernel is C#? Look, it even loads amicoolyet Singularity>
Of course, C# is my least favorite example of such languages, and there are far better ways of accomplishing type safety that don't end up removing mad pointer tricks as a method of accomplishing something.
As for this little Brainfuck argument, Luis is going to argue it in the wrong direction. Brainfuck could be a really nice language with the right tools. For example, you could give it a DLL containing wrappers to the standard C library. " would be LoadLibrary, ' would be GetProcAddress, » would push an argument, « would call the function with the pushed arguments and store the return value. Because the code would be so horribly redundant (having to load a new proc address every time you want to call a function), an optimizer could boil the code down to nothing. It might even be faster than C++. :O ...Until you need to pass arguments that aren't strings.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
luiscubal
|
|
Reply #42 Posted on: June 05, 2010, 02:03:34 pm |
|
|
Joined: Jun 2009
Posts: 452
|
"Also, that same bloat can get in the way of adding new features to C++." Care to give an example? Lately it shouldn't appear the committees are having any trouble introducing new features to the language. Well, judging by the horrible ugly syntax of lambdas in C++0x, it would appear they don't have many options without introducing syntactical ambiguity. Singularity's one screen shot was so transparently propaganda-laden it made me sick. Well, Singularity's core innovation was being in pseudo-C#(I think it's not exactly C#, but I can't remember), so obviously there wasn't much impressive about it aside from that fact and, therefore, being written in C# was probably the only notable detail about Singularity. Of course, C# is my least favorite example of such languages, and there are far better ways of accomplishing type safety that don't end up removing mad pointer tricks as a method of accomplishing something. That could be the root of our disagreements. C# is my favorite language(although I notably hate C# APIs). BTW, C# has pointers. Both IntPtr(a nice safe way to deal with them) and ordinary *& C syntax. The first way is often used with P/Invokes. The second way requires the "unsafe" keyword to be used since, well, it's unsafe. I never needed to use the second syntax. The first syntax I only used for P/Invokes. ...Until you need to pass arguments that aren't strings. Well, Brainfuck has integers. It can represent any type C can. It can represent pointers(in fact, Brainfuck is designed on the concept of pointers), it can represent integers, floating point(see IEEE 754 for how to represent float in integers), it can represent characters and, with that, it can represent strings, structs and unions. So, basically, Brainfuck(with those few command extensions) could do anything.
|
|
|
Logged
|
|
|
|
Rusky
|
|
Reply #43 Posted on: June 05, 2010, 02:49:58 pm |
|
|
Joined: Feb 2008
Posts: 954
|
Now, when you're done raging over the bluntness of that statement, consider its implications. ISO C++ forbids void* arithmetic, it forbids implicit casts between pointers of non-inherited types, and it forbids implicit cast from pointer to integer. The question isn't of whether a separate garbage collector can be slapped on to the output of any old C++ program; that kind of thinking leads to output bloat instead of C85 language bloat that can be ignored. The problem is not solved by ISO C++. You can still say SomeObject* foo = (SomeObject*)0x0BADF00D. Also, you can't pretend that a garbage collector alleviates all allocation problems. Specialized ones, knowing the size of everything up front, can be used to alleviate allocation headaches and just increment a pointer. There's nothing a garbage collector can accomplish that manual can't if given equal thought. Garbage collection has come a long way, and it's typically not an O(N) clusterfuck anymore. That doesn't mean that they are programmed with magic that fixes all our resource problems. Garbage collectors alleviate allocation headaches, which is more than enough for a lot of uses. The rest is just to show you that GC is fine for other uses as well. It improves memory locality (and thus cache usage), makes code more readable (which further helps productivity) and makes new techniques feasible (sane closures, etc.). I don't see any of those as being exceptionally large... Looking at Xmonad, it's built off of X, which only serves to help my point. The rest are little things like RapidSVN that I kind of take for granted because really, they're just nice wrappers to what I'd otherwise be doing in a terminal.
Also, I can be missing a huge, huge project made in Haskell without "making things up." I'm reporting my findings. I indicated what would "probably [be] notice[d]," based off of my findings. Quit accusing me of making things up simply because you disagree with my point. You still haven't done your research. Darcs is a full, distrubted version-control system- not a wrapper. Yi is a full text editor which improves on Vim and Emacs. GHC is a full, bootstrapping, optimizing, production-quality Haskell compiler. Cabal is a full package manager, with a better interface than apt-get. Xmonad is built on X the same way Gnome and KDE are, and it shows that Haskell is fine at interop. seL4's prototype was implemented in Haskell to prove it's behavior. You can write large systems just fine in languages even as high-level as Haskell. Care to give an example? Lately it shouldn't appear the committees are having any trouble introducing new features to the language. Half of C99 got ignored. They ignored GC support (not built-in GC, nobody wants that in C++). They mostly added pointless things that could have been solved much better by removing or fixing something else.
|
|
|
Logged
|
|
|
|
|