1

A friend of mine told me that this code has some problems:

#include <iostream>
#include <cstdio>
using namespace std;
#define cout printf   
int main(){
    cout("cout");
}

He didn't give me the reason and asked me to figure it out which I couldn't. The code seems to be working fine, what could possibly be wrong with it?

7
  • 11
    It's wrong because you're redefining cout to be an alias of printf. And the two are completely different animals. Commented May 25, 2011 at 17:51
  • 10
    It's not wrong technically. It's wrong morally. I think that's what your friend meant. Commented May 25, 2011 at 17:53
  • It is almost certainly going to become wrong technically as well, and likely sooner rather than later. Commented May 25, 2011 at 17:54
  • 6
    "Seems to be working" is like "I crossed the street without looking, wasn't run over by a bus". Wanna try again? Commented May 25, 2011 at 17:56
  • 3
    Redefining existing names with the preprocessor is always wrong. Commented May 25, 2011 at 17:57

5 Answers 5

11

As far as I know the Standard forbids defining names (with #define) declared in any standard library header.

Found this in n3290 ($17.6.4.3.1)

17.6.4.3.1 Macro names [macro.names]

1 A translation unit that includes a standard library header shall not #define or #undef names declared in any standard library header.

Sign up to request clarification or add additional context in comments.

8 Comments

I'm pretty certain this is true, but I'll be snookered if I can find proof. I know it applies to keywords at the very least, but cout is hardly a keyword.
Names are not keywords, and keywords can never be declared or defined. As such it certainly applies to cout.
So in other words, if he removed the #include <iostream> line, his program would be legal, just confusing. As of now, it needn't even compile.
It's legal to write an infinite recursive loop that locks up your application.
@Prasoon, @Dennis: I don't know where you find it exactly, but mine n3290 copy says "A translation unit that includes a standard library header shall not #define or #undef names declared in any standard library header.", so removing <iostream> doesn't make it a valid program since it still includes cstdio.
|
2

While you may argue that this code "seems to be working fine", consider a few years down the line when your 7-line source file is a 7-hundred-line source file and you are not the only maintainer.

You've moved on from writing C-style printf statements in C++ source files and you add (or another maintainer adds) the following line of perfectly valid C++:

    cout << "What is wrong with my perfectly valid C++ code? " << endl;

And your compiler reports:

test.cpp:699: error: invalid operands of types ‘int ()(const char*, ...)’ and ‘const char [29]’ to binary ‘operator<<’

A whole world of pain!

Comments

2

Yes. It has problem.

Since its C++, one may habitually write cout << 1000 which would be an error in this case, but which is otherwise very normal in C++.

What next? Are you trying to define this:

#define scanf cin

//so that you can use it as
scanf >> variable; //not so kewl.

My advice is :

Don't try to change the meaning of such names. What will you get by doing so, after all? Nothing.

Comments

1

It's got maintenance problems, because you'd redefined well-known features to work differently. So no other programmer will want to work on this code.

Similar:

#define MULTIPLY(a, b) (a + b)

#define FIVE 12
#define THREE 3

int main(void)
{
    return MULTIPLY(FIVE, THREE);
}

It gives the right answer, but is totally unmaintainable.

Comments

0

You have declared main as returning int, but have not included a return statement. You should add a return 0; to the end of the main function. In C++ you don't have to return a value from main, but it's good style.

Oh, and don't #define cout printf, it's really confusing. It may not be technically illegal, but it's not nice for whoever comes later to try to maintain your code.

1 Comment

If you don't return anything from main, the compiler will implicitly return 0. That's not an error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.