Don't Overlook Efficient C/C++ Cmd Line Processing
An anonymous reader writes "Command-line processing is historically one of the most ignored areas in software development. Just about any relatively complicated software has dozens of available command-line options. The GNU tool gperf is a "perfect" hash function that, for a given set of user-provided strings, generates C/C++ code for a hash table, a hash function, and a lookup function. This article provides a reference for a good discussion on how to use gperf for effective command-line processing in your C/C++ code."
I would not consider speed of command line option processing to be bottleneck in any application, the overhead of starting of the program is far greater.
I'm not sure that for the usually simple task of command line processing, I'd like to learn a whole new lex/yacc syntax thingy.
Religion is what happens when nature strikes and groupthink goes wrong.
This has to be a joke? Sheesh. Someone found a "new" toy?
it does create some good-looking code.
Does the phrase "reinvent the wheel" strike a chord with anyone?
I do. On MIPS, ARM, PPC, x86, and all the other embedded stuff. I don't think C will ever die - it's the universal assembler language.
Good grief. What a strawman of an example.
Anyone writing or maintaining command line programs knows that they
should be using the API getopt() or getopt_long().
There are standards on how command line options and arguments are to be
processed. They should be followed for portability and code maintenance.
OCaml for the win
There's this little project of which you may have heard: http://www.kernel.org/
Oh, gee, well, nobody except:
1) Every linux kernel developer
2) Every *BSD kernel developer
3) John Carmack, for the core of every ID engine up to and possibly beyond Doom3
4) You, whenever you compile C++ code, as it is compiled to C before machine code (unless you are using an exotic compiler such as the Compaq AXP C++ compiler for TRU64).
import sys
...
...}
def function_1 (...):
functions = {'a': function_1,
'b': function_2,
'c': self.method_1,
func = functions[value]
if __name__ == '__main__':
args = sys.argv[1:]
func(args)
# The variable "functions" is set to a Python dictionary.
# Built-in dictionaries already use fast hash-table lookups.
I use C for any low-level programming project that doesn't warrent an object-oriented approach.
The trick is to identify the best tool for the job.
I'm currently rewriting Post Road Mailer, which is in C on OS/2. I also wrote a e-mail scanner. It all depends on what you need to do.
I did a phone interview for a job a couple of years ago. Remote underwater sensor equiptment. Had to run on battery, you think they would have written in in C or C++? It would once in a while turn on the hard drive one the flash drive was full.
The more you abstract something, the less efficient it becomes.
There are millions of lines of COBOL code still running.
"The Jenolan could probably fly rings around the Enterprise on impulse." Geordi LaForge.
Fight Spammers!
What kind of joke is this? The example in listing 1 is using strtok() to do something it can't do, and even if it did what the authors intended, they wrote comments documenting something else.
Just about any relatively complicated software has dozens of available command-line options.
That should probably be rephrased to "Just about any relatively complicted software that inflicts command-lines on its users..."
This is clearly a very unix oriented post as there are relatively few command-line windows apps and few window GUI apps that accept command-lines. But this is also a topic that's about as old as programming itself and clearly something that takes the "new" out of "news".
http://www.tiobe.com/tpci.htm/
You, whenever you compile C++ code, as it is compiled to C before machine code (unless you are using an exotic compiler such as the Compaq AXP C++ compiler for TRU64).
Excuse me???? That was not even true anymore when I started using C++, back in 1992. There are features in the C++ standard that are so extremely difficult to correctly implement in standard compliant C that it's a complete waste of effort trying to pass via C while compiling. Exception handling comes to mind as the prime example. A failed attempt to support exceptions was the reason why Cfront 4.0 was abandoned. Note that 3.0 was released as early as 1991. The last Cfront based compiler I had the horor of using was HP's CC. It was superseeded by the new native aCC by 1994 at the latest.
By the way, I used to write C/C++ compilation/optimisation stuff for a living, so I guess I know something about the topic.... :-)
Linux user since early January 1992.
There's a time and place for gperf - command line argumnet processing is not it!
Actually, I've never really come across a case where I knew ahead of time the whole universe of strings I would be accepting, and so never ended up using it - gperf is a great idea, but this seems to be a case of someone really looking hard to figure out where they could shoehorn gperf into just for the sake of using it.
"There is more worth loving than we have strength to love." - Brian Jay Stanley
You are wrong about 3):
Source: http://archive.gamespy.com/e32002/pc/carmack/
And 4) as well:
Source: http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/G_002b _002b-and-GCC.html
Pretty much every embedded program in existence. Own a printer? Thats several hundred thousand lines of C in there.
I still have more fans than freaks. WTF is wrong with you people?
GCC parses C++ to it's tree IR; there is no translation to C.
thing is, 'the world' is built an C/C++ and this won't change soon, everywhere you look it's C/C++ libs and stuff. ;/
i'm trying desperately to move away from C++, it's dusty and a hell of a language with loads of problems BUT the average neighborhood library has a C (or C++) interface. So either you fiddle around with more or less weird X to C call libraries, or you stick with C/C++. sad but that's the way it is
I haven't even read TFA, but I know that gperf isn't for command lines; getopt() (in its various forms) more than adequately does its job.
One real use of gperf and perfect hashes that I know of is in TAO (The ACE ORB), an implementation of CORBA. Since CORBA includes the class and method names as strings, a perfect hash speeds up each lookup of the actual routine to call.
In modern times, I can imagine gperf (or a Java/C#/Ruby/whatever port) speeding up SOAP or other XML-based protocols.
...it's more than a little pointless to use it for command-line options, especially in C++. For
one thing, as others have pointed out, I have a hard time imagining a case in which command-line
parsing is a real bottleneck for any application. And, given that that's the case, having to write
lots of special functions and use extra tools for something that is a problem solved well through
freely-available libraries seems like something of a waste of time. I assume that the true purpose of
the article was to remind people of gperf.
Respectfully to the IBM authors, you might as well just use lex and perhaps yacc if you're
dealing with C and need to write a parser, or a library that does a much better job of handling
command-line options (such as GNU getopt) and their problems which range far beyond merely parsing
things.
With C++, you have available those libraries as well, but if you want to try other approache, Boost
("http://www.boost.org") has a very nice command-line option library that also sports an expressive
notation for describing the options in code.
In any case, it's nice to see an article on gperf, but here it felt somewhat rediculously applied.
It's been many years since most C++ compilers used C as an intermediate language. CFront did, and some EDG-based compilers do, but most current C++ compilers do not.
C does have its strengths, such as the relative simplicity of C90 and its lack of dependency on sophisticated compilers and runtimes, but its use as an IL is largely historical.
Perfect hash functions are curiosities. If you have a static set of keys, then with enough work you can generate a perfect (i.e. collision-free) hash function. This has been known for many years. The applicability is highly limited, because you don't usually have a static set of keys, and because the cost of generating the perfect hash is usually not worth it.
Gperf might be reasonable as a perfect hash generator for those incredibly rare situations when the extra work due to a hash collision is really the one thing standing between you and acceptable performance of your application.
I thought maybe we were seeing a bad writeup, but no, it's the authors' themselves who talk about the need for high-performance command-line processing, and give the performance of processing N arguments as O(N)*[N*O(1)]. I cannot conceive of a situation in which command-line processing is a bottleneck. And their use of O() notation is wrong (they are claiming O(N**2) -- which they really don't want to do, not least because it's wrong). O() notation shows how performance grows with input size. Unless they are worrying about thousands or millions of command-line arguments, O() notation in this context is just ludicrous.
I don't know why I'm going on at such length -- the extreme dumbness of this article just set me off.
"Command-line processing is historically one of the most ignored areas in software development."
This is like saying that walking is historically one of the most ignored areas in human transportation.
Wish I had some mod points, great reply.
If it's not, the author of that article should be kept as far away from writing software as possible; he epitomizes the attitude that so frequently gets C++ programmers into trouble.
else if (! strncmp (argv[i], "-print-file-name=", 17))
Maybe they're just too scared of its present options processing to change it.
C is indeed not a good intermediate language for the reasons you mentioned. :-)
But C-- may be (http://cminusminus.org/)
Perhaps the kernel developers should be coding in *that* language
If Pandora's box is destined to be opened, *I* want to be the one to open it.
I don't think C++ compilers compile to C anymore... I know Borland's TPC did this, but that was back when C++ was built on top of C.
Where's the Foot icon? Optimizing command line parsing? Oh God, my sides are splitting.
First of all, how many programs have command line parsing as a bottleneck?
Secondly, they should put this functionality into GCC instead, so that it creates a perfect hash for any large switch statement.
If moderation could change anything, it would be illegal.
Are you seriously trying to argue that gperf is more portable than getopt?
At least the Comeau C++ compiler still generates C code, and is known as one of the most portable and standard-compliant C++ compilers (including support for exported templates!). So compiling C++ to C is definitely a viable strategy (although I can understand compiler vendors that want to offer a complete toolchain take a different approach).
It only uses a 'subset' of c++ called c ;)
----
Go canucks, habs, and sens!
You, whenever you compile C++ code, as it is compiled to C before machine code
One of my Computer Science Profs said something similar. He argued that C and C++
are basically the same outdated shit and professionals would only use Java in real-world
applications. The best thing: He ran Ubuntu and all sorts of Gnome stuff on his Laptop.
I've probably used more time typing this message than every program I've ever run has used parsing command line arguments.
Here's something you've all been waiting for: the AT&T public domain source for getopt(3). It is the code which was given out at the 1985 UNIFORUM conference in Dallas. I obtained it by electronic mail directly from AT&T. The people there assure me that it is indeed in the public domain.
There is no manual page. That is because the one they gave out at UNIFORUM was slightly different from the current System V Release 2 manual page. The difference apparently involved a note about the famous rules 5 and 6, recommending using white space between an option and its first argument, and not grouping options that have arguments. Getopt itself is currently lenient about both of these things White space is allowed, but not mandatory, and the last option in a group can have an argument. That particular version of the man page evidently has no official existence, and my source at AT&T did not send a copy. The current SVR2 man page reflects the actual behavor of this getopt. However, I am not about to post a copy of anything licensed by AT&T.
I will submit this source to Berkeley as a bug fix.
I, personally, make no claims or guarantees of any kind about the following source. I did compile it to get some confidence that it arrived whole, but beyond that you're on your own.
Do you even lift?
These aren't the 'roids you're looking for.
While I agree that most modern compilers can out optimize the average programmer, you are still looking at generalities.
Both compilers and abstract container class have to deal with generalities which may not apply to YOUR specific case. The class writer does not know the specific case or conditions (presuming you are not writing the class for that specific condition). A class writer has to (or should be) check arguments and conditions, where if you know it has been checked (and am damn well sure) you can skip that.
When writing an abstration layer, you are adding a layer.
On the other hand, a good programmer would not try to optimize a bubble sort. I was working on a resource compiler (in DOS) back in 1989. It would take 45 minutes to 'compile'. I rewrote it to take about 3:15 minutes. But during the writing my AVL btree insert was taking forever. A would allocate the memory to do the insert, when it found the word was in there, it would free it. Deferring the allocation fixed that.
If you know the entire program/system you can better optimize.
Fight Spammers!
?!?!?\N{INTERROBANG}
Talk about overkill. gperf is for parsers. Yeah, I know getopt is itself a parser, but I think anyone who's done real programming knows what I mean.
Besides, perfect hashes are old and busted. Cuckoo hashes give you almost identical performance and are far more flexible.
The following two directories should bring it up to the latest version I know of.
This is not efficient, mind you. Command line parsing doesn't generally need to be efficient, even by my miserly standards, honed when a PDP-11 was something you hoped to upgrade to... some day...
ftp://ftp.uu.net/usenet/comp.sources.misc/volume2
ftp://ftp.uu.net/usenet/comp.sources.misc/volume3
http://www.cmcrossroads.com/bradapp/ftp/src/libs/
http://www.cmcrossroads.com/bradapp/ftp/src/libs/
Wackinteluntilandows?
Winapackatindows?
Please! Expand that wildstar! Whatever could it match?
It sounds like the author is statically linking his library and running on embedded an embedded system. It is not surprising in that case that the c++ standard library brings in much more code than the c standard library, but it should be made clear that it is not relevant to desktop developers, pretty much all of which dynamically link with glibc.
Again, to be clear, dynamically linking with the c++ standard library is not going to increase your executable size. Please don't try to roll your own code that exists in the standard library. It is a real nuisance when people do that.
I should qualify that by saying that template instantiations do (of course) increase executable size, but that they do so no more than if you had rolled your own.
There are features in the C++ standard that are so extremely difficult to correctly implement in standard compliant C that it's a complete waste of effort trying to pass via C while compiling.
The only thing I can imagine that would be hard to map directly onto C would be exceptions. Can you confirm that this is what you mean? Because nothing else comes to mind that would be "extremely difficult" to implement.
Even then, it's possible to emulate C++-style exceptions in C. I've done it -- the best description I can think of is "horrifically ugly." But it's possible.
In the embedded realm (not to mention kernel or driver space stuff for any OS), you won't be using much C++. Granted, I've used both in the embedded world, and I prefer C++ whenever I can get away with it. But that ain't often.
One of the problems with C++ in the embedded market is not the language itself, but the mindset of the developers. Most folks who do low-level stuff are not as concerned with code structure and organization as they are the size and speed of the generated code. (Don't believe that? Try working under a tight schedule.) Many of them abhor C++ for its complexity, and more than a few in my experience also don't have enough experience with C++ to use it effectively anyway.
For example, when I worked on a platform that had to be up 24/7 (this wasn't something you'd buy from Best Buy, 'kay?), some enterprising soul tried his hand at C++ and put the following statement in a constructor:
Brrr.
Not much C++ occurred in the organization after that one sneaked in.
--- The American Way of Life is not a birthright. Hell, it's not even sustainable.
This is kinda silly. If you only have a few keywords you don't need anything sophisticated. If you have more then a few but not more then a few dozen its usually easiest just to arrange them in a linear array and do an index lookup based on the first character to find the starting point for your scan. More then that and you will want to hash them or arrange them in some sort of topology such as a red-black tree.
... case ... }. This is equivalent to the use of some sort of data structure but it winds up being coded and optimized directly by the compiler, and it's very easy to understand the resulting source code.
Generally speaking hashes are very cpu and cache-inefficient beasts, especially if one can reap the benefit of the locality of reference you get with other schemes. Hashes are easy to implement, though, so if you have a lot of keywords and there is either no locality of reference anyway or you don't care about the performance, a hash works just fine.
Insofar as strings go, once you get beyond a certain point its easiest to just hash the string on the front-end, deal with any collisions on the front-end as well (aka implement a string table and modify the hash value for one of the strings if a collision occurs), and then simply reference the string via its hash value in the remainder of the program instead of actually doing any further string comparisons. As an extention of this one can use a larger 64-bit hash and consider any collisions to be fatal. This is extremely viable for a language parser given that the chances of a collision actually occuring are so low you might only get one, or even zero, across the entire domain of source code in existence today.
If you have a fixed set of keywords, then a 16 or 32 bit hash is usually sufficient to avoid collisions. At this point you just generate a header file with the values and switch on them. e.g. hv = hash(str); switch(hv) { case KEYWORD_FOR:
-Matt
Which means that using at the command line is "linking" it. Doing so, of course, means your upstream code must be GPL as well. Ad Infinitum. Sorry, but the bulk of c/c++ code out there is non-gpl licensed and therefor can take no advantage of tools such as this.
Of course C++ exceptions are what I meant. What else would I mean when using the word "exceptions" in this context?
And yes, C++ exceptions can be expressed in C. After all, C is a glorified assembler and the resulting code from C++ translation is assembler as well. It all depends in the level of abstraction at which write the C code is written and on the amount of uglyness/inefficiency you're willing to take on board (and also the trade-off between both of the latter). But that's not the point. The point of this thread is that nowadays it makes no sense to make use of this capability in a C++ compiler. Especially not when considering that a user of a C++ compiler wants more than just a compiler. He also wants a debugger that is able to meaningfully link up the binary and the original C++ source. If you're a C++ compiler vendor, using C as an IL does nothing but complicate your own life. Twice.Linux user since early January 1992.
When faced with this issue, I simply wrote a Windows version of getopt. Took about a day.
Even when reinventing the wheel, it is important to reinvent as little as possible. If you need functionality that isn't there, at least keep the same interface.
The cake is a pie
When you have 'goto', and 'return', what's so difficult about implementing exceptions in vanilla C ? Even in APIs - you just 'goto' some point that sets a flag and returns, and the 'trying' API-using caller checks the flag upon return. If the namespaces don't clash, it's not a problem at all !
Religion is what happens when nature strikes and groupthink goes wrong.
Try supergetopt instead. Much easier to use and also open source.. 1.tgz
http://www.ibiblio.org/pub/Linux/devel/sugerget-1
With this code, you simply specify command-line strings and variables in a printf()
style format.
E.g. supergetopt( argc, argv,
"string1", "%d %d", function1,
"string2", "%s", function2 )
will call function1( int a, int b ) when string1 is on the command line,
and will call function2( char *s ) when string2 is used on the command line.
A whole lot easier than gperf, IMHO.
What about Boost.Program_Options? I thought I'd see a post on it here somewhere, but not one person has mentioned it (yet).
A few months ago, I was looking around for a C++ library for parsing command line options. I checked out get_opt and I thought that there must be something that uses std::string instead of char*. After some googling, I found Boost.Program_Options seemed to be exactly what I was looking for. It supports long and short options (-s,--short) and I was able to start using it quite easily after looking at the tutorials.
The main problem (but not the only one) is called "object destructors". You have to make sure they are called. All of them, and in the correct order, at all the nested scopes of execution you are in when the exception occurs. And you need to make sure not to call them on any object not yet constructed (always remember that constructors can throw exceptions too) and never to call a destructor twice (I've seen this kind of bug multiple times in multiple compilers). And then there is the fun of exceptions thrown by destructors, not to mention the possibility that it all happens in the middle of constructing or destructing an array of objects.
All that is why setjmp()/longjmp(), also known as C's non-local goto, don't cut it, which in turn means that you need to complicate function return mechanisms. And just when you think you got that problem sorted out, you need to be aware that C++ functions can call (library) C functions that were never compiled to even know about exceptions but that in turn can call C++ functions that may again throw an exception. The entire construction needs to be able to handle this.
As I wrote in an other post in this thread, it can be done. But it is not easy. Note that the entire object destructor issue also applies within a single scope, which is why life is not as easy as replacing every "throw" statement by "goto end;".
Linux user since early January 1992.
2 words: constructors and destructors.
A constructor may throw an exception; partially-constructed objects may not be destructed. Not only you have destruct the objects in the reverse order, but have to figure out which objects to destruct. It's much more complex than plain return or goto.
Not only that, exceptions aren't supposed to slow down your program when you don't throw any; so to compile efficiently, you have to maintain some specialized data structures to avoid "checking for exceptions" for every function call.
Then there's the catch block: if you throw a Child object you can catch it as a Mother class; and C++ allows multiple-inheritance (thanks God^H^H^HStroustrup), so at every catch block you have to test (efficiently) if the types match.
So I don't think a compiler supporting just goto and return can acceptably implement exceptions.
it doesn't make sense at all! strtok doesn't work that way, it takes a list of separators (like space and tabs) between the tokens,
Even if this was meant to be 'strcmp', the return value would be zero so it would have been if (!strcmp(...))
very bizzare, it's like the article wasn't reviewed at all
Interestingly, C is no longer a proper subset of C++.
Are you seriously trying to use such a blatant and obvious strawman?
GLaDOS for President 2016! "Well here we are again. It's always such a pleasure." -- GLaDOS, 2011
Absolutely. There is no platform for which gperf is a better, more portable option for command line processing than getopt. I'm not sure what you think getopt does that is "tricky" under Win32. Its a string processor.
When faced with the issue of implementing getopt on Windows, I merely took the code from FreeBSD: src/lib/libc/stdlib/getopt.c
:-/)
I love FreeBSD. (I once changed the motherboard, rebooted, went, "Oh.. shit," and proceeded to login. All drivers are compiled as modules, in less time than my lean linux kernel.
I sidestepped the license issue, stripped out extraneous header files, changed a couple referenced to _getprogname() (either to static string "" or to a global var, as it is in libc), read the man page to figure out how to use it and had a short-form option parser in.. probably under an hour.
Some things you have to code. For everything else, the Regents of the University of California has done it for you.
Years ago I spent a few minutes and 30 lines of code later I had a command line parser that placed arguments into an associative array. Its used in roughly 90% of our stuff nowadays and saved a little bit of time although we thankfully don't have much to do /w CLI.
:)
The central problem is command line arguments can sometimes be very very complex and very hard to account for in a systematic manner mostly because the argument lists, consumption of parameters etc may very well depend on what those parameters actually are meaning your better off keeping a global arg consumption counter with that big switch statement than going off trying to find some system to abstract what will be more complex to abstract anyway.
Or could the real problem be the complex argument lists? I guess it depends on the specifics of the system but from my personal experience I don't think its fair to assume people ignore this sort of thing completely.
Also Efficiency and one time parsing of an arg list... WTF!?!? What year is this, how many GHZ do CPUs run and we're talking about efficiency of CLI parsing. I think I'll shake my head in disbelife and move on
Right, but the great-great-grandparent never said gperf is more portable than getopt. What he did say was that getopt() doesn't work on Windows and that it only handles short arguments. From that, you drew a conclusion not supported by the facts in evidence (to put it in lawyer speak).
GLaDOS for President 2016! "Well here we are again. It's always such a pleasure." -- GLaDOS, 2011
Again, on the off chance that this helps anyone reading this pitifully long and silly thread: it is trivial to make getopt work on Win32, just like it was trivial to make strsep work on Linux when it only had strtok. I object to the argument that "portability" has anything whatsoever to do with whether you'd use getopt to parse arguments.
Like most of the other comments on this post, I find the idea of using gperf for "high performance argument parsing" superfluous and convoluted. In fact, I find the idea of a general-purpose perfect hash tool a bit superfluous as well; gperf languishes in obscurity for a reason.
Ok, but at that point you have already called their constructors, so you have a list. Just working down that same list calling all the destructors doesn't seem that much of a problem.
Religion is what happens when nature strikes and groupthink goes wrong.
I still use it. I have not been able to find an e-mail program that will run on OS/2 that allows me to attach notes to e-mails w/o effecting the original e-mail. The PRM stickynote feature.
It does cause fits for opposing counsel when I provide the files in OS/2 format.
Fight Spammers!
powershell anything can be done in MS latest server products.
The power is exactly what most here addres as a problem with arguments.
Answer tot that problem is make everything as object orientated.
this is the last devolpment and has the goods of unix and MS combined.
The creater actualy worked once for unix, but improved shortcomming in an new language.
it's even more powerfull then what we could do with vbs (integrate for example excel and file/user management etc).
it can now pass whole object to change... like a bit having a wmi base command in a oneliner. (altough not limited to oneliners).
Well in short the problem isn't the language it's about what you can do with it in a server environment.
Yup, and it's called Parrot, and it's currently being developed. (There's also the Java VM which has some undocumented cross-language support. It was designed for Java but you can compile other language with special compilers to byte code and run them successgully). (There's also the
The only question is : what language will THAT VM be written into ?
That's the trick : most of the high level languages like Perl, etc. are designed to be run on VMs, and most of the time produce bytecode (for exemple, there's still no 100% sure way to compile perl into machine code as of today). Not all of them can output something that can be run on the CPU.
So for now, all VMs are themselves produced in C.
Maybe in embed market you will see processors with specialised unit for VM-bytecode (as it is currently available with Java on some feature phones), but won't see the x86-legacy architecture being displaced by it any time soon. It's very hard to change such legacy as the IA64 vs. AMD64 has proven.
I also dread the day when the whole GUI itself is running inside the VM like the ass ugly and horribly slow Java's. Highlevel language are nice for glue-coding, for putting together other technologies (from libraries) together into an application, but GTK itself or some computing library into a JVM would be hell.
"Sufficiently advanced satire is indistinguishable from reality." - [Tips: 1DrYakQDKCQ6y52z6QbnkxHXAocMZJE61o ]
Or perhaps you mean that C++ is no longer a proper superset of C, considering the history behind the two.
> Unless they are worrying about thousands or millions of command-line arguments
Clearly they are thinking of the next version of ls...
I find std::map to be quite sufficient for this purpose.
For great justice.
Kind of surprised no one has mentioned SimpleOpt yet. It's public domain, lightweight, self-contained, and works great. I've been using it for quite a while in a C++ project and I've been very happy with it. It's also designed explicitly to be cross-platform and not depend on platform-specific features, whereas e.g. getopt would not necessarily be available on a given platform.
Then your professor is a fool. When Java can do metaprogramming, we can talk. It's an invaluable tool for trading off run-time flexibility for speed. Most polymorphism is in fact completely static.
Who uses the Command Line Interface (CLI) anymore. It seems with each release of Windows, we are raising a generation of useless "Pointers and Clickers' who are prone to repetitive-strain-injury RSI.
Want to change the extension of 100 files in windows, good luck pointing and clicking.
Want to add 100 users in Windows, and set default/random passwords, good luck pointing and clicking.
Heck, with XP home, just point and click your username.
I am the Alpha Troll. Vengeance is mine, sayeth the Alpha Troll; I will pre-pay!
C is C. Assembler is not C. C is not Assembler.
Which section of which manual details how to reduce the binary footprint of <iostream> in static libstdc++? I read the libstdc++ FAQ, but it just says that you can replace g++ with gcc -lsupc++ if you need new and delete but not <iostream>. It states that splitting up parts of libstdc++ into individual sections is currently not implemented due to implementation defects in GNU ld's garbage collection; is there a good way to work around this?
Or which query in which Web search engine should I use? I tried iostream binary footprint in Google and iostream code size in Google, but I didn't see anything relevant in the first pages.
And what is GHOC? The Green Hills Optimizing Compiler. Thank you. But why are Green Hills products sold on a "call for price" basis?Your professor sounds exactly like a student.