I am using gcc 4.2.4.
According to Schildt, "C++ The Complete Reference", 1995, user defined parameterized manipulators should be defined as:
istream &mymanip(istream &stream, type param)
{
// here my code
return stream;
}
// overload
imanip<type> mymanip(type param){
return imanip<type>(mymanip, param)
}
// usage
cin >> mymanip(param);
I believe that imanip(mymanip, param) is supposed to return an object that contains mymanip and mymanip's arguments. This should be used by an overloaded operator>> to call mymanip. However, this does not work, imanip is not declared.
I also found this version:
IMANIP(int) fld(int n){
return IMANIP(int)(fld,n);
}
which also does not work.
My questions are:
does gcc 4.2.4 follow the ANSI C++ standard on this detail or not? If it does, did the standard change since 1995 in this respect?
in order to define my own parameterized manipulators do I need to understand the iostream code and write my own overloaded imanip and operator>> functions?
regardless the answer to question 2, what is the best strategy for me to understand the iostream code? Should I read the code? How do I find out the names of compiled libraries which are part of iostream? Should I read a book?
The code you posted seems out of context. imanip looks like some template, but that template is never defined anywhere in your code.
But to be honest, I would not even consider using a 1995 book on C++ any more. In 1995 C++ was not even standardized, although there existed an "annotated reference manual". Your book is over 17 years old, which means "more than extremely outdated" when it comes to programming languages. C++ has evolved a lot since then, you should consider to buy a more recent book, perhaps take a look at http://isocpp.org/get-started to give you some examples.
To give you more specific answers to your questions:
Yes, gcc follows the standard in this regard, but your book might not, because it is pre-standard.
Manipulators are made so you do not have to reimplement the op<< and op>> again. However, depending on what your manipulators are designed to do, you might need to call some of the lower level methods provided by the stream or streambuf.
"The code" does not exist, there are several implementors of standard libraries, and they all have their own, sometimes very complicated code for etc. I would recommend to search the web for information about how those libraries work. Of course, a book is even better. Consider buying "The C++ Standard Library" by N. Josuttis. There is a recent Edition that covers the standard library "as of now and tomorrow", i.e. including the additions of the C++11 standard.
Related
I'm reading the JSF AV C++ Coding Standards and the rule 22 says:
AV Rule 22 (MISRA Rule 124, Revised)
The input/output library <stdio.h> shall not be used.
Is there any reason to not use <stdio.h>?
I know that these rules are for C++ and we can use <iostream>... but what's wrong with <stdio.h>?
Every now and then, there are questions like this, about why some coding standard mandates this or that.
The correct answer should always be: Whatever the authors of that coding standard intended. Sometimes, a coding standard gives reasons for its rules; this one apparently does not. Therefore, we can only guess what the answer to your question might be.
I'll thus add my own guess:
Air vehicles sounds like really serious business, with extremely high correctness and robustness requirements. printf, scanf et al make it easy to write code which happily passes the compiler but creates undefined behaviour at run time.
Those C functions do have one advantage to normal C++ streams: format strings make it easier to write internationalised code. Consider this quickly made-up example using an std::ostream for some UI component such as a button label in a customer management application:
os << "Update customer\n";
You might want to dynamically add the customer's name:
os << "Update " << customer_name << "\n";
And you might want to dynamically insert the foreign-language word for "Update":
os << InternationalString(id_update) << " " << customer_name << "\n";
However, this is inherently English-centric. It will product correct English strings like "Update John" or "Update Joe", but will e.g. fail for German, which has different grammar and requires strings like "John aktualisieren" or "Joe aktualisieren", with the name in front of the verb in this case.
This is where format strings shine:
sprintf(s, FormatString(id_update_customer), customer_name);
Depending on the application's language setting, such a FormatString function may return "Update %s" or "%s aktualisieren".
Still, it's very dangerous. As a matter of fact, if customer_name in my example above was a std::string, you'd have undefined behaviour already.
Libraries like Boost.Format try to combine the flexibility of format strings with the type safety of streams.
Going back to your actual question, my guess is that flexibility with regards to international strings is not a great concern in the air-vehicles business.
As you can see, every aspect of a coding standard can be discussed at great length. The reasons for individual rules may not always be so apparent, and they will often have something to do with the application domain for which the standard was written.
If you cannot ask the author of the coding standard, then your question cannot really be answered.
The most obvious problem would be the lack of type safety in printf, scanf, and their various cousins (e.g., sprintf).
Along with the type safety problems, the scanf and sprintf families make it fairly difficult to ensure against buffer overruns. It can be done, but it's not trivial, and it would appear that only a tiny minority of C programmers have any clue of how to handle these kinds of tasks at all.
This JSF C++ standard is referencing MISRA-C:1998 and both are related to use of the C language in safety critical systems. The latest standard, MISRA-C:2012 has been updated (providing more rationale and better examples), and MISRA Rule 124 is now Rule 21.6 "The Standard Library input/output functions shall not be used".
The rationale is pretty simple: streams and file I/O have unspecified, undefined and implementation-defined behaviours associated with them. Also included in the guideline are the references to the C standards (C90 and C99) sections where these unpredictable behaviors are described.
The rule can be broken (through a deviation process) if the actual implementation is well defined or the code is shown not to be critical.
I have been working in C and C++ and when it comes to file handling I get confused. Let me state the things I know.
In C, we use functions:
fopen, fclose, fwrite, fread, ftell, fseek, fprintf, fscanf, feof, fileno, fgets, fputs, fgetc, fputc.
FILE *fp for file pointer.
Modes like r, w, a
I know when to use these functions (Hope I didn't miss anything important).
In C++, we use functions / operators:
fstream f
f.open, f.close, f>>, f<<, f.seekg, f.seekp, f.tellg, f.tellp, f.read, f.write, f.eof.
Modes like ios::in, ios::out, ios::bin , etc...
So is it possible (recommended) to use C compatible file operations in C++?
Which is more widely used and why?
Is there anything other than these that I should be aware of?
Sometimes there's existing code expecting one or the other that you need to interact with, which can affect your choice, but in general the C++ versions wouldn't have been introduced if there weren't issues with the C versions that they could fix. Improvements include:
RAII semantics, which means e.g. fstreams close the files they manage when they leave scope
modal ability to throw exceptions when errors occur, which can make for cleaner code focused on the typical/successful processing (see http://en.cppreference.com/w/cpp/io/basic_ios/exceptions for API function and example)
type safety, such that how input and output is performed is implicitly selected using the variable type involved
C-style I/O has potential for crashes: e.g. int my_int = 32; printf("%s", my_int);, where %s tells printf to expect a pointer to an ASCIIZ character buffer but my_int appears instead; firstly, the argument passing convention may mean ints are passed differently to const char*s, secondly sizeof int may not equal sizeof const char*, and finally, even if printf extracts 32 as a const char* at best it will just print random garbage from memory address 32 onwards until it coincidentally hits a NUL character - far more likely the process will lack permissions to read some of that memory and the program will crash. Modern C compilers can sometimes validate the format string against the provided arguments, reducing this risk.
extensibility for user-defined types (i.e. you can teach streams how to handle your own classes)
support for dynamically sizing receiving strings based on the actual input, whereas the C functions tend to need hard-coded maximum buffer sizes and loops in user code to assemble arbitrary sized input
Streams are also sometimes criticised for:
verbosity of formatting, particularly "io manipulators" setting width, precision, base, padding, compared to the printf-style format strings
a sometimes confusing mix of manipulators that persist their settings across multiple I/O operations and others that are reset after each operation
lack of convenience class for RAII pushing/saving and later popping/restoring the manipulator state
being slow, as Ben Voigt comments and documents here
The performance differences between printf()/fwrite style I/O and C++ IO streams formatting are very much implementation dependent.
Some implementations (visual C++ for instance), build their IO streams on top of FILE * objects and this tends to increase the run-time complexity of their implementation. Note, however, that there was no particular constraint to implement the library in this fashion.
In my own opinion, the benefits of C++ I/O are as follows:
Type safety.
Flexibility of implementation. Code can be written to do specific formatting or input to or from a generic ostream or istream object. The application can then invoke this code with any kind of derived stream object. If the code that I have written and tested against a file now needs to be applied to a socket, a serial port, or some other kind of internal stream, you can create a stream implementation specific to that kind of I/O. Extending the C style I/O in this fashion is not even close to possible.
Flexibility in locale settings: the C approach of using a single global locale is, in my opinion, seriously flawed. I have experienced cases where I invoked library code (a DLL) that changed the global locale settings underneath my code and completely messed up my output. A C++ stream allows you to imbue() any locale to a stream object.
An interesting critical comparison can be found here.
C++ FQA io
Not exactly polite, but makes to think...
Disclaimer
The C++ FQA (that is a critical response to the C++ FAQ) is often considered by the C++ community a "stupid joke issued by a silly guy the even don't understand what C++ is or wants to be"(cit. from the FQA itself).
These kind of argumentation are often used to flame (or escape from) religion battles between C++ believers, Others languages believers or language atheists each in his own humble opinion convinced to be in something superior to the other.
I'm not interested in such battles, I just like to stimulate critical reasoning about the pros and cons argumentation. The C++ FQA -in this sens- has the advantage to place both the FQA and the FAQ one over the other, allowing an immediate comparison. And that the only reason why I referenced it.
Following TonyD comments, below (tanks for them, I makes me clear my intention need a clarification...), it must be noted that the OP is not just discussing the << and >> (I just talk about them in my comments just for brevity) but the entire function-set that makes up the I/O model of C and C++.
With this idea in mind, think also to other "imperative" languages (Java, Python, D ...) and you'll see they are all more conformant to the C model than C++. Sometimes making it even type safe (what the C model is not, and that's its major drawback).
What my point is all about
At the time C++ came along as mainstream (1996 or so) the <iostream.h> library (note the ".h": pre-ISO) was in a language where templates where not yet fully available, and, essentially, no type-safe support for varadic functions (we have to wait until C++11 to get them), but with type-safe overloaded functions.
The idea of oveloading << retuning it's first parameter over and over is -in fact- a way to chain a variable set of arguments using only a binary function, that can be overload in a type-safe manner. That idea extends to whatever "state management function" (like width() or precision()) through manipulators (like setw) appear as a natural consequence. This points -despite of what you may thing to the FQA author- are real facts. And is also a matter of fact that FQA is the only site I found that talks about it.
That said, years later, when the D language was designed starting offering varadic templates, the writef function was added in the D standard library providing a printf-like syntax, but also being perfectly type-safe. (see here)
Nowadays C++11 also have varadic templates ... so the same approach can be putted in place just in the same way.
Moral of the story
Both C++ and C io models appear "outdated" respect to a modern programming style.
C retain speed, C++ type safety and a "more flexible abstraction for localization" (but I wonder how many C++ programmers are in the world that are aware of locales and facets...) at a runtime-cost (jut track with a debugger the << of a number, going through stream, buffer locale and facet ... and all the related virtual functions!).
The C model, is also easily extensible to parametric messages (the one the order of the parameters depends on the localization of the text they are in) with format strings like
#1%d #2%i allowing scrpting like "text #2%i text #1%d ..."
The C++ model has no concept of "format string": the parameter order is fixed and itermixed with the text.
But C++11 varadic templates can be used to provide a support that:
can offer both compile-time and run-time locale selection
can offer both compile-time and run-time parametric order
can offer compile-time parameter type safety
... all using a simple format string methodology.
Is it time to standardize a new C++ i/o model ?
The canonical way to read lines from a text file is:
std::fstream fs("/tmp/myfile.txt");
std::string line;
while (std::getline(line, fs)) {
doThingsWith(line);
}
(no, it is not while (!fs.eof()) { getline(line, fs); doThingsWith(line); }!)
This works beacuse std::getline returns the stream argument by reference, and because:
in C++03, streams convert to void*, via an operator void*() const in std::basic_ios, evaluating to the null pointer value when the fail error flag is set;
see [C++03: 27.4.4] & [C++03: 27.4.4.3/1]
in C++11, streams convert to bool, via an explicit operator bool() const in std::basic_ios, evaluating to false when the fail error flag is set
see [C++11: 27.5.5.1] & [C++11: 27.5.5.4/1]
In C++03 this mechanism means the following is possible:
std::cout << std::cout;
It correctly results in some arbitrary pointer value being output to the standard out stream.
However, despite operator void*() const having been removed in C++11, this also compiles and runs for me in GCC 4.7.0 in C++11 mode.
How is this still possible in C++11? Is there some other mechanism at work that I'm unaware of? Or is it simply an implementation "oddity"?
I'm reasonably certain this is not allowed/can't happen in a conforming implementation of C++11.
The problem, of course, is that right now, most implementations are working on conforming, but aren't there completely yet. At a guess, for many vendors, this particular update is a fairly low priority. It improves error checking, but does little (or nothing) to enable new techniques, add new features, improve run-time efficiency, etc. This lets the compiler catch the error you've cited (some_stream << some_other_stream) but doesn't really make a whole lot of difference otherwise.
If I were in charge of updating a standard library for C++11, I think this would be a fairly low priority. There are other changes that are probably as easy (if not easier) to incorporate, and likely to make a much bigger difference to most programmers.
To use one of the examples you gave, if I were in charge of updating the VC++ standard library to take advantage of the compiler features added in the November CTP, my top priority would probably be to add constructors to the standard container types to accept initialization_lists. These are fairly easy to add (I'd guess one person could probably add and test them in under a week) and make quite an obvious, visible difference in what a programmer can do.
As late as GCC 4.6.2, the libstdc++ code for basic_ios is evidently still C++03-like.
I'd simply put this down to "they haven't gotten around to it yet".
By contrast, the libc++ (LLVM's stdlib implementation) trunk already uses operator bool().
This was a missed mini-feature buried in a pre-existing header. There are probably lots of missing error of omission and commission in pre-2011 components.
Really, if anyone comes up with things like this in gcc then it would do a world of good to go to Bugzilla and make a bug report. It may be a low priority bug but if you start a paper trail
I'll go out on a limb and extend this idea to all the other C++ compilers: clang, Visual Studio,etc.
This will make C++ a better place.
P.S. I entered a bug in Bugzilla.
I am learning C, and after starting out learning C++ as my first compiled language, I decided to "go back to basics" and learn C.
There are two questions that I have concerning the ways each language deals with functions.
Firstly, why does C "not care" about the scope that functions are defined in, whereas C++ does?
For example,
int main()
{
donothing();
return 0;
}
void donothing() { }
the above will not compile in a C++ compiler, whereas it will compile in a C compiler. Why is this? Isn't C++ mostly just an extension on C, and should be mostly "backward compatible"?
Secondly, the book that I found (Link to pdf) does not seem to state a return type for the main function. I check around and found other books and websites and these also commonly do not specify return types for the main function. If I try to compile a program that does not specify a return type for main, it compiles fine (although with some warnings) in a C compiler, but it doesn't compile in a C++ compiler. Again, why is that? Is it better style to always specify the return type as an integer rather than leaving it out?
Thanks for any help, and just as a side note, if anyone can suggest a better book that I should buy that would be great!
Firstly, why does C "not care" about the scope that functions are defined in, whereas C++ does?
Actually, C does care. It’s just that C89 allows implicitly declared functions and infers its return type as int and its parameters from usage. C99 no longer allows this.
So in your example it’s as if you had declared a prototype as
int dosomething();
The same goes for implicit return types: missing return types are inferred as int in C89 but not C99. Compiling your code with gcc -std=c99 -pedantic-errors yields something similar to the following:
main.c: In function 'main':
main.c:2:5: error: implicit declaration of function 'donothing' [-Wimplicit-function-declaration]
main.c: At top level:
main.c:5:6: error: conflicting types for 'donothing'
main.c:2:5: note: previous implicit declaration of 'donothing' was her
For the record, here’s the code I’ve used:
int main() {
donothing();
return 0;
}
void donothing() { }
It's because C++ supports optional parameters. When C++ sees donothing(); it can't tell if donothing is:
void donothing(void);
or
void donothing(int j = 0);
It has to pass different parameters in these two cases. It's also because C++ is more strongly typed than C.
int main() {
donothing();
return 0;
}
void donothing() { }
Nice minimum working example.
With gcc 4.2.1, the above code gets a warning regarding the conflicting types for void donothing() with default compiler settings. That's what the C89 standard says to do with this kind of problem. With clang, the above code fails on void donothing(). The C99 standard is a bit stricter.
It's a good idea to compile your C++ code with warnings enabled and set to a high threshold. This becomes even more important in C. Compile with warnings enabled and treat implicit function declarations as an error.
Another difference between C and C++: In C++ there is no difference between the declarations void donothing(void); and void donothing(); There is a huge difference between these two in C. The first is a function that takes no parameters. The latter is a function with an unspecified calling sequence.
Never use donothing() to specify a function that takes no arguments. The compiler has no choice but to accept donothing(1,2,3) with this form. It knows to reject donothing(1,2,3) when the function is declared as void donothing(void).
he above will not compile in a C++ compiler, whereas it will compile in a C compiler. Why is this?
Because C++ requires a declaration (or definition) of the function to be in scope at the point of the call.
Isn't C++ mostly just an extension on C
Not exactly. It was originally based on a set of C extensions, and it refers to the C standard (with a few modifications) for the definitions of the contents of standard headers from C. The C++ "language itself" is similar to C but is not an extension of it.
and should be mostly "backward compatible"?
Emphasis on "mostly". Most C features are available in C++, and a lot of the ones removed were to make C++ a more strictly typed language than C. But there's no particular expectation that C code will compile as C++. Even when it does, it doesn't always have the same meaning.
I check around and found other books and websites and these also commonly do not specify return types for the main function
The C and C++ standards have always said that main returns int.
In C89, if you omit the return type of a function it is assumed to be int. C++ and C99 both lack this implicit int return type, but a lot of C tutorial books and tutorials (and compilers and code) still use the C89 standard.
C has some allowances for implementations to accept other return types, but not for portable programs to demand them. Both languages have a concept of a "freestanding implementation", which can define program entry and exit any way it likes -- again, because this is specific to an implementation it's not suitable for general teaching of C.
IMO, even if you're going to use a C89 compiler it's worth writing your code to also be valid C99 (especially if you have a C99 compiler available to check it). The features removed in C99 were considered harmful in some way. It's not worth even trying to write code that's both C and C++, except in header files intended for inter-operation between the languages.
I decided to "go back to basics" and learn C.
You shouldn't think of C as a prerequisite or "basic form" of C++, because it isn't. It is a simpler language, though, with fewer features for higher-level programming. This is often cited as an advantage of C by users of C. And an advantage of C++ by users of C++. Sometimes those users are the same people using the languages for different purposes.
Typical coding style in C is different from typical coding style in C++, and so you might well learn certain basics more readily in C than in C++. It is possible to learn low-level programming using C++, and the code you write when you do so may or may not end up looking a lot like C code.
So, what you learn while learning C may or may not inform the way you write C++. If it does, that may or may not be for the better.
C++ has changed these rules on purpose, to make C++ a more typesafe language.
C.1.4 Clause 5: expressions [diff.expr]
5.2.2
Change: Implicit declaration of functions is not allowed
Rationale: The type-safe nature of C++.
Effect on original feature: Deletion of semantically well-defined feature. Note: the original feature was
labeled as “obsolescent” in ISO C.
Difficulty of converting: Syntactic transformation. Facilities for producing explicit function declarations
are fairly widespread commercially.
How widely used: Common.
You can find other similar changes in appendix C of this Draft C++ standard
Isn't C++ mostly just an extension on C
No. If you think of C++ as "C with Classes", you're doing it very, very wrong. Whilst strictly, most valid C is valid C++, there's virtually no good C that's good C++. The reality is that good C++ code is vastly different to what you'd see as good C code.
Firstly, why does C "not care" about the scope that functions are
defined in, whereas C++ does?
Essentially, because not enforcing the same rules as C++ makes doing this in C hideously unsafe and in fact, nobody sane should ever do that. C99 tightened this up, along with implicit-int and other defects in the C language.
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.
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.
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.
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!-).