views:

1376

answers:

3

This is a totally hypothetical question, but I have to know the answer.

I assume most C++ compilers are written in assembly. Which makes them different languages entirely (I could be wrong). That being said if I were going to create a cout style function for plain old C, how would I do it? cout has some very impressive features take this snippet for example:

// endl not only prints a new line but also flushes the stream
cout << "Hello World!" << endl;

Which I'm pretty sure translates to this in C:

printf("Hello World!\n");
fflush(1);                  //stdout = 1

Next order of business, the << operators. In C++ this would be easy (operator overloading), but I can't think of a single way to do this in C.

+3  A: 

That's right, because C does not have operator overloading, you cannot change the behaviour of the << operator, it will always do a bit shift, so there is no way to write 'cout' with the precise semantics it has in C++, in C.

Out of interest, g++ (GNU C++ Compiler) is written mostly in C.

David Claridge
+3  A: 

C is actually a popular implementation language for C++ compilers and standard libraries (so is C++ itself, actually -- a concept sometimes known as self-hosting or bootstrapping a language), and you can study the whole sources of a rich, complex C++ standard library (plus extensions) here (sorry, this is gcc 3 -- can't find a gcc 4 source tree that's just as easily browseable online, though of course you can easily download those sources and study them on your local machine).

Personally, I would suggest starting instead with a good book, such as this one -- the sources will be much more meaningful to you once you've got a good grasp of all the obscure nooks and crannies of C++'s iostreams (as a bonus, the book also takes you on a guided tour through locales -- hold on to your hat!-).

Alex Martelli
+11  A: 

It may help in thinking about this to translate between the "<<" operator syntax and the "operator<<" function syntax. Your C++ example is equivalent to this bit of C++ code:

operator<< ( operator<< (cout, "Hello World!"), endl);

The first thing that you should notice here is that there is not actually a lot of cleverness in cout at all. What is clever is the operator<< function -- specifically, the version of the operator<< function that takes a stream object (which is what cout is, but many other things are too) as its first argument. Or, even more precisely, the range of operator<< functions that take a stream object as the first argument, and take a particular thing as the second argument -- there's one for each type of object that you can put into the cout stream. You can see one of the C++ tricks in that syntax, too; the operator<< functions on stream objects always return the stream object that they were given, thereby allowing chaining of this nature.

In order to put C++ code into linkers and system ABIs that expect C-like function syntax, most C++ compilers "mangle" the function names, in order to encode in them the type of arguments that they have. (Also, of course, the "<<" isn't a valid C-like function name.) So, if you looked at the generated assembly for this bit of function, you'd see that the names of the two functions were different from each other -- they'd have suffixes indicating the argument types. You could do something like that manually:

operator_lshift__stream__endl(
  operator_lshift__stream__string(cout, "Hello World!"), endl);

And there you've got something that you could implement in C.

Brooks Moses