std::cout or printf

Discussion of chess software programming and technical issues.

Moderators: hgm, Harvey Williamson, bob

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
User avatar
lucasart
Posts: 3018
Joined: Mon May 31, 2010 11:29 am
Full name: lucasart
Contact:

Re: std::cout or printf

Post by lucasart » Wed Nov 14, 2018 5:33 am

mar wrote:
Wed Nov 14, 2018 1:00 am
lucasart wrote:
Tue Nov 13, 2018 11:24 pm
This is typically the result of the "design by a committee" approach:
* some idiot, who just discovered namespaces, and wet his pants dreaming about them says: hey this is awesome, we should encapsulate C library in a namespace too!
* someone else, likely the political kind, who knows it's a stupid idea, but doesn't want to say it to not offend the aforementioned idiot says: hum... ok, but let's not break backward compatibility, so we'll duplicate everything, with and without 'std::'.

Which is why good language design, and good design generally, can never result from committee decisions. The benevolent dictator approach is far superior, and avoids this kind of nonsense.
Yes, well. I think anyone can write a proposal and it may/may not make it into the standard.
Generally speaking, I think it's better to have a couple of competent people rather than hundreds of random guys proposing random stuff
that solves absolutely nothing and just adds unnecessary bloat.

I'll rant a bit about things I dislike about C++ now, take it with a grain of salt (IMO/YMMV) :)

There were some good changes since C++11, but also some disasters. Obviously this is a matter of opinion, it's hard to satisfy everybody...
The only thing that's obvious is that it gets more and more complicated and bloated, C++ is not elegant nor pretty.

I wonder how this shit made it into the standard btw: http://www.stroustrup.com/C++11FAQ.html#gc-abi
Nobody implemented it, nobody every uses it. GC is NOT the way to manage memory. Especially in realtime applications.
Of course you can use Boehm GC for C++ which scans the whole heap, all stacks of all threads and all registers, i believe "stop the world" type of GC with potential FPs.

In C++ or C, you can manage memory any way you want, preferrably on stack, you can write pool allocators, LIFO allocators or anything you need.
GC is for inexperienced programmers and solves nothing, you can still get leaks plus you get unknown and potentially unbounded performance hit that can occur at any time, lifetime of allocated objects is unknown, no control over actual memory usage.

I consider exceptions a disaster, many will probably disagree but yeah, if you don't mind tagging lots of functions with noexcept and like the false impression that your code is more robust with exceptions, go on. It's really just a hard-to-debug super-goto over several stack frames. Not to mention that probably nobody can write complicated code with strong exception safety without performance loss, those who think so are just delusional or never went beyond hello world scale.
Now good luck if someone loves to try {} catch(...) {} or throws across dynamic library boundaries :D

Multiple/virtual inheritance is another abortion, no need to go into details here.

The good thing about C++ on the other hand is that unless someone is forcing you, you don't have to use all the fancy features it offers just to be cool, it's still a very powerful language.

Another thing is move semantics. It solves like 2 problems but adds 20 more, a whole new layer of complexity. Many (not only beginners) actually
don't even understand how it works. std::move moves nothing, just "removes reference", it's actually move constructors and move assignment operators that do the heavy lifting;
so when you move from, you basically perform a shallow copy (+target cleanup in the case of move assignment) plus you need to invalidate the source object, because it will still be destroyed.
Now the symbol used for rvalue references means something else in templates and auto, in templates you also have to use std::forward if you want "perfect forwarding". A tremendous mess if you ask me.
Now people typically "move everything" because it's so cool, but it's really pointless to "move" POD types.
Also some even std::move return values, but don't understand that this will break RVO/NRVO, which is now actually even mandatory in recent standard.
So the only benefit is that the compiler can do default move ctor for you, but the price is rather high. I'd prefer a good auto-generated swap operator anytime which would be orders of magnitude simpler.

Now the standard library. I would say there are some good things, just streams is not one of them, they're so bad it's not even funny.
The standard imposes a lot of unecessary restrictions on some containers, so you waste tons of memory for various sets and maps which do heap allocation per node by default.
I don't know if this applies to all implementations, but std::map or std::set allocates root in constructor, this is also horrible, a good container should never allocate in default ctor. Fortunately there're custom allocators but still... set<int> typically consumes some 32 bytes per node in 64-bit mode, now add some 16 bytes heap block overhead...
Now heap allocations are very well optimized these days, most likely pooled for small blocks, they scale relatively well unless you start to allocate large blocks and get fried on global heap mutex or something like that.
Sure, you can use custom allocators (if I'm not mistaken the API still lacks realloc, which sucks)

Now someone wants to add a "2d rendering" library as part of the std, based on some ancient cairo, the API is absolutely horrible and reference implemention is piece of shit written by someone who doesn't have a clue, but this is actually really happening http://www.open-std.org/jtc1/sc22/wg21/ ... 0267r8.pdf

Next time some idiot will want to embed chromium... I can imagine std::browser :)

And I forgot the evergreen, UB :) so that optimizers can do bogus optimiziations that will only trigger in some artificial nonsense cases that you'll never benefit from in real world code (but you'll benefit from long debug sessions and headaches if you're not careful :)

Anyway - until Blow finishes Jai, I'll stick with C/C++ :)
Lol.

Think of all the time wasted learning that encyclopedic pile crap. In the same amount of time, imagine what you could have done with a simple and pragmatic language like golang…

I wonder how big the next C++ encyclopedia will be. C++2017 standard is already well above 2000 pages, right?
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.

Dann Corbit
Posts: 9067
Joined: Wed Mar 08, 2006 7:57 pm
Location: Redmond, WA USA
Contact:

Re: std::cout or printf

Post by Dann Corbit » Wed Nov 14, 2018 7:56 pm

For my way of thinking, if I am going to write a C project, I write a C project and use functions.
If I am going to make a C++ project, I write a C++ project and use classes.
I will admit that once in a while I do something lazy like printf or sprintf inside a C++ toy project of some kind. But I prefer to take my time and do it right.

The two languages are extremely different for me, and beautiful in their differences.

C is a tiny, terse language and you can grasp the whole of the grammar very easily. It is simple, fast, and close to the machine.

C++ is a very complex language with templates, overloading, the STL, and inheritance. I think it is not as complex as Java, which is too damn complex.

How many frameworks are part of the Java language, and just what are the real edges of the Java language? Having a language owned by a company instead of a standard body is a bad idea. (Same for dotnet). Without a formal ISO/ANSI standard, there is no clear definition that you can rely on. It's like the wild west days of C and Fortran before there were standards written for them.

With C++ I can encapsulate and abstract and make things easy to visualize. With C, I can write simple code that is right next to the heart of the machine. C is (essentially) a high level assembler. C++ is like another abstraction layer above that (perhaps a special assembler with C as a target in some sense).

But I do not think one language is better than another. It is also a myth that C++ reduces complexity. C++ hides complexity. That's not the same thing.

And I think that robust, efficient projects can be written in either language. The Postgresql database is written in C, and it is marvelous. MySQL is a mixture of C and C++ and it is marvelous. Stockfish is a marvelous C++ project.

The excellence of the outcome depends a lot more on the skill of the workers than the language chosen (so long as it is compiled). I guess that a real Fortran expert could write a Fortran95 version of a chess engine that is every bit as good as the best out there.

A good algorithm is more important even than a good language choice. A dotnet or Java program with great algorithm choices will clobber a compiled program full of bad algorithm choices.
Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.

mar
Posts: 1886
Joined: Fri Nov 26, 2010 1:00 pm
Full name: Martin Sedlak

Re: std::cout or printf

Post by mar » Thu Nov 15, 2018 8:29 am

I agree with most that you wrote. But Java really is super-simple compared to C++, I'd even say it's trivial.
C++ is easily the most complex language out there (and I don't think it's a good thing, sane people don't like complexity).

I also don't think that the comparison of C and high level assembly is appropriate, I'd put it way higher than that. In fact, when I was switching
from pascal to C a long time ago, I was absolutely excited about the language. Nothing like that happened when I was switching from C to C++.

When it comes to C# or Java, it's all fine if you don't mind running 2x slower than equivalent C/C++ programs, especially chess programs.
I have no real explanation as I don't believe that array bounds checking that the compiler cannot move out of loops would be the only culprit,
and GC obviously won't trigger for a chess engine either, so I don't know, but it's a fact.

Unlike some synthetic benchmarks and/or where a guy compares to C/C++ code with optimizations disabled.
I remember when Peter rewrote Cuckoo from Java to C++, he got like 100+ elo
tscp in C# runs 2x slower than in C

Needless to say I don't like either Java or C#

Oh and speaking of ISO, if you want to read the C++ standard, you have to buy it :) It should be a good read, most likely more pages than War and Peace
Martin Sedlak

AlvaroBegue
Posts: 901
Joined: Tue Mar 09, 2010 2:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: std::cout or printf

Post by AlvaroBegue » Thu Nov 15, 2018 3:30 pm

mar wrote:
Thu Nov 15, 2018 8:29 am
I agree with most that you wrote. But Java really is super-simple compared to C++, I'd even say it's trivial.
C++ is easily the most complex language out there (and I don't think it's a good thing, sane people don't like complexity).

I also don't think that the comparison of C and high level assembly is appropriate, I'd put it way higher than that. In fact, when I was switching
from pascal to C a long time ago, I was absolutely excited about the language. Nothing like that happened when I was switching from C to C++.

When it comes to C# or Java, it's all fine if you don't mind running 2x slower than equivalent C/C++ programs, especially chess programs.
I have no real explanation as I don't believe that array bounds checking that the compiler cannot move out of loops would be the only culprit,
and GC obviously won't trigger for a chess engine either, so I don't know, but it's a fact.

Unlike some synthetic benchmarks and/or where a guy compares to C/C++ code with optimizations disabled.
I remember when Peter rewrote Cuckoo from Java to C++, he got like 100+ elo
tscp in C# runs 2x slower than in C

Needless to say I don't like either Java or C#

Oh and speaking of ISO, if you want to read the C++ standard, you have to buy it :) It should be a good read, most likely more pages than War and Peace
When I went from Pascal to C, I barely noticed the difference. Yes, the syntax is more compact and some things made more sense in C, like char being a small integer. I took a program I had written in Pascal and translated it to C as a learning project, and a whole bunch of "chr"s and "Ord"s vanished in a puff of smoke, leaving a much more readable program behind.

I do think of C as high-level assembly. I have programmed in assembly for Z80 and x86, and I have a very good idea of what a naive translation of the C code would look like in assembly. C++ is a very different language from C. There are many things in C++ language whose implementation is not immediately obvious (exceptions, lambda expressions, std::function).

The true strength of C++ is that it allows you to define clean interfaces between parts of the code. A well-designed C++ library (e.g. SFML) is a thing of beauty.

Unfortunately, C++ is very complex, and this gives programmers too many ways to mess things up.

Joost Buijs
Posts: 772
Joined: Thu Jul 16, 2009 8:47 am
Location: Almere, The Netherlands

Re: std::cout or printf

Post by Joost Buijs » Thu Nov 15, 2018 5:13 pm

My feeling is that C++ is not very different from C at all, its just C with extensions. Most programs written in C compile with very minor changes (like the function headers) also in C++.

What I like about C++ are: Operator overloading, Templates, Variable Templates, Constant Expressions, and even Exceptions can make your life very easy at times.

What I don’t like is most of the stuff in the std::library and things like Polymorphism, Inheritance and Lambda Expressions where I never found good use for.

Out of curiosity I still maintain a copy of my engine in Pascal (using Free Pascal), what a cumbersome language that is to write a chess program in. It really lacks a lot of things that makes life so easy when using C/C++. I like the concept of units with an interface and implementation section, that is very clean, better than C++ where you get crazy sometimes about circular references in your header files, but for all other things I prefer C++. Free Pascal is a lot less efficient as well, the Pascal version my engine with exactly the same algorithm runs at least 40% slower as the one in C++. Maybe Embarcadero (Delphi) is more efficient, but I never tried that one.

mar
Posts: 1886
Joined: Fri Nov 26, 2010 1:00 pm
Full name: Martin Sedlak

Re: std::cout or printf

Post by mar » Thu Nov 15, 2018 5:15 pm

Let's agree to disagree. I wonder where this misconception comes from, but C is NOT high level assembly, not even close.
LLVM IR may be considered "high level assembly", but the term itself is dubious.

I too did a lot of assembly in the past but C really is nothing like it, not even if you use some advanced assemblers like NASM (if it still exists)
Refactoring a C program is easy, now try to refactor assembly.
C is portable, assembly not at all.

Ergo C is a programming language, not assembly language.

(By this definition, Java/C# could be called high level bytecode, which wouldn't make much sense either:)
Martin Sedlak

Ras
Posts: 1021
Joined: Tue Aug 30, 2016 6:19 pm
Contact:

Re: std::cout or printf

Post by Ras » Thu Nov 15, 2018 5:33 pm

mar wrote:
Thu Nov 15, 2018 8:29 am
It should be a good read, most likely more pages than War and Peace
LOL - epic rant!
Rasmus Althoff
https://www.ct800.net

Rein Halbersma
Posts: 678
Joined: Tue May 22, 2007 9:13 am

Re: std::cout or printf

Post by Rein Halbersma » Sat Nov 17, 2018 11:23 am

mar wrote:
Thu Nov 15, 2018 8:29 am
Oh and speaking of ISO, if you want to read the C++ standard, you have to buy it :) It should be a good read, most likely more pages than War and Peace
Nobody buys the official Standard, the latent draft is always freely available: https://github.com/cplusplus/draft (unders papers, most recent doc)
Fun fact: the last Committee meeting had an agenda of 274 proposals, more words than the collected works of Shakespeare. :) https://herbsutter.com/2018/11/05/pre-t ... diego/amp/

Post Reply