0

Let's assume that I have a program with many files and many cout's, and for debug purposes I would like to disable output for a moment, but only in a single file.

It is just out of curiosity question, I know that I shouldn't do that to disable output, but I started to wonder when facing this problem, and it only shows properly what I mean.

I tried to create a #define macro, but I can't replace the whole line, only a single symbol (with params).

For example:

//some common header file
#ifdef DISABLE_OUTPUT
#define cout... void; //?? DK exactly what should i put here
#endif

//other file
#include "commons.h" //my macro
#define DISABLE_OUTPUT

void foo()
{
    ...
    cout << "blablabla" << 4 << "something" << endl; // should be removed
    ...
}

If DISABLE_OUTPUT is defined, the whole line should be replaced with void; (better clear the line).

The problem is that I don't know how to clear the whole line with #define.

Is there any "magic" symbol or trick that I can use?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Macias
  • 657
  • 4
  • 16
  • 1
    Make a object of a dummy class, which has `operator<<()` overloaded (which does nothing) and make `#define cout NAME_OF_THE_DUMMY_OBJECT`, something like: https://ideone.com/kv381z – mch Sep 19 '17 at 17:20
  • The actual question si: "_Why_ do you want to use a macro?" Don't use macros without reason. Why not use a function for the statement and a macro to call it. `void;` is invalid in both langugages C and C++. And don't double-tag questions, C is not C++ is not C! – too honest for this site Sep 19 '17 at 17:23
  • @mch I was thinking about it, but is there any way to do that without defining the class? – Macias Sep 19 '17 at 17:28
  • Why don’t you want to define the class? – Daniel H Sep 19 '17 at 17:28
  • `#define cout if ( 0 ) cout` would work ... some of the time. – AJNeufeld Sep 19 '17 at 17:30
  • You may be interested in sort-of-but-not-quite duplicate question : https://stackoverflow.com/questions/4810516/c-redirecting-stdout – François Andrieux Sep 19 '17 at 17:33
  • @Olaf I don't want to use macro in this particular case and I've wrote that. just want to know if i can replace the whole line with #define... – Macias Sep 19 '17 at 17:36
  • 1
    Oh, this was just out of curiosity? I think a lot of people here, including myself, didn’t quite realize that and thought you intended to use this code. Curiosity is a much better reason to ask this. – Daniel H Sep 19 '17 at 17:39
  • @Macias: Erm … what do you think `#define` is for? A good C++ book would be a start. – too honest for this site Sep 19 '17 at 17:39
  • @DanielH Exactly, just curiosity :) Edited now for the short-sighted – Macias Sep 19 '17 at 17:50

1 Answers1

3

It’s a bad idea to define a macro with the same name as a standard library component, so you shouldn’t #define cout at all. I’m going to assume you #define disableable_cout instead.

The simplest answer would be to define it like this:

#ifdef DISABLE_OUTPUT
#define disableable_cout if (false) cout
#else
#define disableable_cout cout
#endif

And then update the cout line in foo to this:

disableable_cout << "blablabla" << 4 << "something" << endl;

Which would expand to either this:

if (false) cout << "blablabla" << 4 << "something" << endl;

if DISABLE_OUTPUT is defined, or to this:

cout << "blablabla" << 4 << "something" << endl;

if DISABLE_OUTPUT were not defined.

Then, if DISABLE_OUTPUT is defined, the output line is skipped; if not, it will happen.

Alternately, you could require DISABLE_OUTPUT is always defined, to either 0 (don’t disable) or 1 (do disable). Then you could use a single definition, like this:

#define disableable_cout if (!DISABLE_OUTPUT) cout

Note that, either option is fragile, like most macros, but it should work in the typical case.

Daniel H
  • 7,223
  • 2
  • 26
  • 41
  • Yes i know that, 'I know that isn't a best way to do that, but its not the case.' – Macias Sep 19 '17 at 17:33
  • @Macias Even given that I thought it was worth warning about the fragility. Or do you mean my warning against declaring a macro with the same name as something in the standard library? – Daniel H Sep 19 '17 at 17:36
  • In this case, I think `#define DISABLE_OUTPUT` would have to be changed to either `#define DISABLE_OUTPUT 1` (or 0), or to an actual variable: `static const bool DISABLE_OUTPUT = true;` (or false). – Remy Lebeau Sep 19 '17 at 19:52
  • @RemyLebeau Ah, fair. Another option would be to keep the `#ifdef` lines, and use `if (false) cout`. – Daniel H Sep 19 '17 at 19:57