std::cout or printf

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

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

Re: std::cout or printf

Post by AlvaroBegue »

Am I the only one that happily uses std::cout without any problems? You can look at uci.cpp in RuyDos.
User avatar
phhnguyen
Posts: 1434
Joined: Wed Apr 21, 2010 4:58 am
Location: Australia
Full name: Nguyen Hong Pham

Re: std::cout or printf

Post by phhnguyen »

Me too. I have converted all my printf code into std::cout. Now I almost forget which characters should go after %! :D

IMO, a std::cout line is usually a bit longer than a printf but it looks more C++ (I don't like mixing C and C++ code) and more straightforward; changing a std::cout should be a bit easier; I don't have to worry about variant types nor errors when using different compilers (VS vs gcc)
https://banksiagui.com
The most features chess GUI, based on opensource Banksia - the chess tournament manager
Ras
Posts: 2487
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: std::cout or printf

Post by Ras »

phhnguyen wrote: Thu Nov 01, 2018 12:41 amnor errors when using different compilers (VS vs gcc)
That's not an issue with modern C either.
Rasmus Althoff
https://www.ct800.net
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: std::cout or printf

Post by lucasart »

cdani wrote: Sun Oct 28, 2018 6:45 am I use this for Andscacs, I don't remember why:

Code: Select all

void afout(const char *fmt, ...)
{
	va_list args;
	char buffer[4096];

	va_start(args, fmt);
	vsprintf(buffer, fmt, args);
	va_end(args);

	fprintf(stdout, "%s", buffer);
	fflush(stdout);
}
Probably because you Ctrl+V'ed it from Fruit :)

This function is just equivalent to printf() + ffslush(). So you may as well replace it by a macro:

#define uci_printf(...) printf(__VA_ARGS__), fflush(stdout)

No need to build a string, and impose a 4096 byte limit.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
User avatar
cdani
Posts: 2204
Joined: Sat Jan 18, 2014 10:24 am
Location: Andorra

Re: std::cout or printf

Post by cdani »

lucasart wrote: Mon Nov 12, 2018 6:02 am
cdani wrote: Sun Oct 28, 2018 6:45 am I use this for Andscacs, I don't remember why:

Code: Select all

void afout(const char *fmt, ...)
{
	va_list args;
	char buffer[4096];

	va_start(args, fmt);
	vsprintf(buffer, fmt, args);
	va_end(args);

	fprintf(stdout, "%s", buffer);
	fflush(stdout);
}
Probably because you Ctrl+V'ed it from Fruit :)

This function is just equivalent to printf() + ffslush(). So you may as well replace it by a macro:

#define uci_printf(...) printf(__VA_ARGS__), fflush(stdout)

No need to build a string, and impose a 4096 byte limit.

Thanks!!
I will do it.
User avatar
WinPooh
Posts: 267
Joined: Fri Mar 17, 2006 8:01 am
Location: Russia
Full name: Vladimir Medvedev

Re: std::cout or printf

Post by WinPooh »

Joost Buijs wrote: Sat Oct 27, 2018 7:16 pm
Uri Blass wrote: Sat Oct 27, 2018 6:40 pm I wonder what do you use and if there is an advantage of std::cout

The main advantage that I see for printf is that it is more convenient to use it but when I search I find that people claim that std::cout is more safe
I try to avoid the std-library as much as possible, C++ has a lot of nice features but IMHO the std-library is not one of them. When you are using MSVC you can also use printf_s which is also more safe than printf.
Than you'd immediately stop using printf, because it's also a part or the C++ standard liblary, defined in header <cstdio>.
mar
Posts: 2554
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: std::cout or printf

Post by mar »

WinPooh wrote: Tue Nov 13, 2018 10:25 am Than you'd immediately stop using printf, because it's also a part or the C++ standard liblary, defined in header <cstdio>.
You got it wrong, printf belongs to C runtime of course. cstdio is shitty wrapper which typically includes stdio.h internally,
no magic here except it injects these C functions into std namespace;
so (typically) you end up with std::printf and also printf in global namespace, you still typically get SEEK_SET as macros and so on.
So the <cxxxx> headers are not really useful at all and all you get is unnecessary clutter of std namespace, better use <stdio.h> directly.
I don't understand how this nonsense even made it into C++ standard, most likely someone got high.
Martin Sedlak
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: std::cout or printf

Post by lucasart »

mar wrote: Tue Nov 13, 2018 2:22 pm cstdio is shitty wrapper which typically includes stdio.h internally,
no magic here except it injects these C functions into std namespace;
so (typically) you end up with std::printf and also printf in global namespace, you still typically get SEEK_SET as macros and so on.
So the <cxxxx> headers are not really useful at all and all you get is unnecessary clutter of std namespace, better use <stdio.h> directly.
I don't understand how this nonsense even made it into C++ standard, most likely someone got high.
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.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
mar
Posts: 2554
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: std::cout or printf

Post by mar »

lucasart wrote: Wed Nov 14, 2018 12:24 am 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++ :)
Martin Sedlak
User avatar
WinPooh
Posts: 267
Joined: Fri Mar 17, 2006 8:01 am
Location: Russia
Full name: Vladimir Medvedev

Re: std::cout or printf

Post by WinPooh »

mar wrote: Tue Nov 13, 2018 2:22 pm
WinPooh wrote: Tue Nov 13, 2018 10:25 am Than you'd immediately stop using printf, because it's also a part or the C++ standard liblary, defined in header <cstdio>.
You got it wrong, printf belongs to C runtime of course. cstdio is shitty wrapper which typically includes stdio.h internally,
no magic here except it injects these C functions into std namespace;
so (typically) you end up with std::printf and also printf in global namespace, you still typically get SEEK_SET as macros and so on.
So the <cxxxx> headers are not really useful at all and all you get is unnecessary clutter of std namespace, better use <stdio.h> directly.
I don't understand how this nonsense even made it into C++ standard, most likely someone got high.
Even more, in some implementations std::cout itself is a wrapper over good old printf().
As for me, I don't strictly prefer one to another, using both of them depending of current project. But as for std::ifstream/std::ofstream, they are much more convenient for me than old-style FILE* fopen()/fclose() stuff.