For example printf
instead of cout
, scanf
instead of cin
, using #define
macros, etc?

- 112,946
- 110
- 377
- 526

- 993
- 12
- 27
10 Answers
I wouldn't say bad as it will depend on the personal choice. My policy is when there is a type-safe alternatives is available in C++, use them as it will reduce the errors in the code.

- 74,600
- 47
- 176
- 233
-
Is there a documentation online where I can see if a function is typesafe or not? – Gustavo Puma Sep 28 '10 at 13:22
-
9If a function takes `void*` arguments, or returns a `void*` result, then it is probably not type-safe. A function with a variable argument list (like `printf`) also generally isn't type-safe. Any time you have to use `sizeof`, the code is probably not type-safe. – Kristopher Johnson Sep 28 '10 at 13:35
-
1@vash47: I don't know of any publication, but you can use the following rules as a start. Variadic functions (such as printf & scanf) are not typesafe, because the compiler can't verify that the variadic arguments have the correct type (except for some special cases). Macros are also less typesafe than inline functions for the same reason. – Bart van Ingen Schenau Sep 28 '10 at 13:36
-
1@vash47: It's implied by the language. C++ attempts to make it difficult to circumvent typing. Naveen refers to C++ versions of the C equivalents, which involve templating and the like. Take a look at your local (and laggy) libstdc++. – Matt Joiner Sep 28 '10 at 13:50
-
It is not just type safety, but also how extendible it is. Most compilers will be able to diagnose with at least a warning if the arguments to `printf` are of the proper types, but even if the compiler ensures that you will not make an error there, you cannot pass any user defined type, so overloading `operator<<` and using `cout` is a solution for a problem that requires a change in syntax in C: `std::cout << "My object is:" << obj << std::ednl;` compared to `printf("My object is: "); obj.print(); printf("\n");` – David Rodríguez - dribeas Sep 28 '10 at 18:20
It depends on which features. Using define
macros in C++ is strongly frowned upon, and for a good reason. You can almost always replace a use of a define
macro with something more maintainable and safe in C++ (templates, inline functions, etc.)
Streams, on the other hand, are rightly judged by some people to be very slow and I've seen a lot of valid and high-quality C++ code using C's FILE*
with its host of functions instead.
And another thing: with all due respect to the plethora of stream formatting possibilities, for stuff like simple debug printouts, IMHO you just can't beat the succinctness of printf
and its format string.

- 263,248
- 89
- 350
- 412
-
4Depends on the use. Boost (universally agreed to be the best library collection for C++) uses macros galore. – Konrad Rudolph Sep 28 '10 at 13:18
-
1@Konrad, agreed, although in any respectful C++ guide (like Effective C++) you'll find whole sections dedicated to why macros in C++ aren't recommended. Besides, by what standards is Boost "best"? Would you say it's best by the readability of its internal implementation? – Eli Bendersky Sep 28 '10 at 13:19
-
1@Eli: I was talking about the interface/functionality, not the implementation. But macros are relevant for that: without the use of macros, Boost couldn’t provide the interface that it provides (in some cases) and would be vastly more difficult to debug and maintain (in other cases). So even though the implementation of Boost is often messy (mainly to cater to noncompliant compilers), macros make the code easier all around. **That said**, I really try to avoid macros where possible (I don’t use them in “normal” code at all). – Konrad Rudolph Sep 28 '10 at 13:29
-
@Konrad: I agree, and my answer actually says "you can *almost* always replace ...", so that's covered – Eli Bendersky Sep 28 '10 at 13:31
-
1@Eli: Somehow, I completely missed that part of the sentence (and the whole thing about templates and inline functions). I can only agree now. – Konrad Rudolph Sep 28 '10 at 13:33
-
1I'm a fan of `printf` as well, but you shouldn't recommend it without pointing out the downside: the lack of type safety and the ease of messing up the match between specs and parameters. – Mark Ransom Sep 28 '10 at 15:43
-
1
-
@Eli: `Boost.Format` should be as easy to use as `printf` and yet be typesafe, isn't it a better alternative ? – Matthieu M. Sep 28 '10 at 18:07
I would say the only ones that are truly harmful to mix are the pairings between malloc
/free
and new
/delete
.
Otherwise it's really a style thing...and while the C is compatible with the C++, why would you want to mix the two languages when C++ has everything you need without falling back?

- 242,243
- 40
- 408
- 536
-
7printf offers you a mechanism for precisely formatting output, which I could not find in cout. – Sep 28 '10 at 13:19
-
3@crypto - cout provides formatting options: http://www.arachnoid.com/cpptutor/student3.html – Justin Niessner Sep 28 '10 at 13:22
-
6cout allows you to format output precisely as well. But the cout way of getting it done is often a lot more complex than the printf way (and vice versa). – Kristopher Johnson Sep 28 '10 at 13:23
-
You should definitely use printf
in place of cout
. The latter does let you make most or all of the formatting controls printf
allows, but it does so in a stateful way. I.e. the current formatting mode is stored as part of the (global) object. This means bad code can leave cout
in a state where subsequent output gets misformatted unless you reset all the formatting every time you use it. It also wreaks havoc with threaded usage.

- 208,859
- 35
- 376
- 711
-
-
2+1, I completely agree. Programming with side effects is evil, and here it is a library standard that imposes this bad behavior :-( – Jens Gustedt Sep 28 '10 at 14:26
-
Of course, the entire design of `std::cout` is that it's an object that stores state. Its main problem is it's lacking a copy ctor; you should be able to make a cheap copy, set state, perform output, and then discard the copy without affecting the original. – MSalters Sep 28 '10 at 15:12
-
1@MSalters: that gets a lot more complicated when you consider buffering and the relationship to threads. I'm sure it could be done with a shared hidden internal object where the buffering and locking took place, with the local state in the wrapper object, but I maintain that it's just bad design. – R.. GitHub STOP HELPING ICE Sep 28 '10 at 16:42
-
`std::cout` as it's designed today is already complicated in that sense. If the formatter state was a separate object, you allow threads to have independent objects. If anything, that _simplifies_ multi-threaded development. – MSalters Sep 30 '10 at 11:37
There are better solutions for most cases, but not all.
For example, people quite often use memcpy
. I would almost never do that (except in really low-level code). I always use std::copy
, even on pointers.
The same counts for the input/output routines. But it’s true that sometimes, C-style printf
is substantially easier to use than cout
(especially in logging). If Boost.Format isn’t an option then sure, use C.
#define
is a different beast entirely. It’s not really a C-only feature, and there are many legitimate uses for it in C++. (But many more that aren’t.)
Of course you’d never use it to define constants (that’s what const
is for), nor to declare inline functions (use inline
and templates!).
On the other hand, it is often useful to generate debugging assertions and generally as a code generation tool. For example, I’m unit-testing class templates and without extensive use of macros, this would be a real pain in the *ss. Using macros here isn’t nice but it saves literally thousands of lines of code.

- 530,221
- 131
- 937
- 1,214
For allocations, I would avoid using malloc/free altogether and just stick to new/delete.

- 5,017
- 3
- 35
- 42
Not really, printf()
is quite faster than cout
, and the c++ iostream library is quite large. It depends on the user preference or the program itself (is it needed? etc). Also, scanf()
is not suitable to use anymore, I prefer fgets()
.

- 15,438
- 7
- 38
- 49
-
3This is wrong: `printf` being faster than `cout` is an urban legend. This really depends on the standard library implementation and on whether or not streams are buffered (but this is the same for C and C++ streams!). `printf` is **not** generally faster than `cout`. It can even be the other way round. Furthermore, `fgets` and `scanf` are completely different (`scanf` does *formatted* input), and `fgets` can be replaced by `cin`. – Konrad Rudolph Sep 28 '10 at 13:24
-
1
What can be used or not only depends on the compiler that will be used. Since you are programming in c++, in my opinion, to maximize compatibility it is better to use what c++ provides instead of c functions unless you do not have any other choices.

- 2,259
- 4
- 26
- 33
Coming from a slightly different angle, I'd say it's bad to use scanf in C, never mind C++. User input is just far to variable to be parsed reliably with scanf.

- 84,577
- 15
- 123
- 161
I'd just post a comment to another reply, but since I can't... C's printf() is better than C++'s iostream because of internationalization. Want to translate a string and put the embedded number in a different place? Can't do it with an ostream. printf()'s format specification is a whole little language unto itself, interpreted at runtime.
-
1Having done translation for commercial products, I find that neither is really suitable. The string "I have %d widgets" just does not translate. Even in English, you need a second string, "I have %d widget" or "I have 1 widget" (as in English, that's the only value which has a different form.) In other languages, you have up to 4 forms, depending of the value of `%d`. Not to mention what happens to format strings when you hand them off to translators. Chances are very high at least one of them will break the `%d`, e.g. by changing it to `% d`. – MSalters Sep 30 '10 at 11:33