Header Files, CommonC++ && All that?
I want to use the class described on the page found here on my SuSE 8.1. (It requiers the CommonC++ documentation to be installed.) file:///usr/share/doc/packages/CommonC++-doc/html/classost_1_1_string_tokenizer.html#_details How would one typically (correctly) include such a library in his code? If I follow K&R 2nd. Ed., they put the #includes for libraries in any .c file that relies on them. Is that technically necessarily? From my experimentation, id doesn't /seem/ to be necessary. All that is required to get the code to run is that the one of the header files referenced in the .c includes the particular library. But 'technically' correct, and stylistically correct are not the same thing. What is the prefered /style/? Is this CommonC++ library really common? If I put it in my code and distribute it, will a bunch of people curse me? Is it the best bag of trick to draw from for general functionality such as string tokenization. I'm writing for a QT/KDE environment. STH
I am under the impression that you just need to declare the library you are going to use like you said, ie: #include <iostream.h> blah blah blah blah or #include<iostream> using std::cout; using std::cin; blah blah blah Unless I misunderstood the question. __________________________________________________ Do you Yahoo!? Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop! http://platinum.yahoo.com
Steven T. Hatton wrote:
How would one typically (correctly) include such a library in his code? If I follow K&R 2nd. Ed., they put the #includes for libraries in any .c file that relies on them. Is that technically necessarily? From my experimentation, id doesn't /seem/ to be necessary. All that is required to get the code to run is that the one of the header files referenced in the .c includes the particular library.
It's not necessary but sometimes makes the code easier to read. Most headers use soemthing like #ifndef CCXX_MISC_H_ #define CCXX_MISC_H_ ... #endif so that if you #include the header more than once, after the first time, the preprocessor will just ignore the content of the header file. Since this is exactly what's in misc.h (header for ost::stringTokenizer), you can include it as often as you like. So #including it more than once is not technically wrong (i.e. it doesn't depend on the compiler to do anything special). I personally tend to use #includes even where they're not needed just for readability: it's a way of saying this class needs something from misc.h even if it's not explicitly stated.
But 'technically' correct, and stylistically correct are not the same thing. What is the prefered /style/?
Is this CommonC++ library really common? If I put it in my code and distribute it, will a bunch of people curse me? Is it the best bag of trick to draw from for general functionality such as string tokenization. I'm writing for a QT/KDE environment.
If there's something in QT that works better, I would use it on the grounds that the more class libraries you use, the greater the chance one won't compile. On the other hand CommonC++ is probably easier to get on any platform than Qt is. Sadly, I didn't know about this class a couple of years' ago when I had to tokenise some input. It could have saved me some work and a buffer overrun. -- JDL
On Tuesday 25 March 2003 02:03 pm, John Lamb wrote:
Steven T. Hatton wrote:
How would one typically (correctly) include such a library in his code? If I follow K&R 2nd. Ed., they put the #includes for libraries in any .c file that relies on them. Is that technically necessarily? From my experimentation, id doesn't /seem/ to be necessary. All that is required to get the code to run is that the one of the header files referenced in the .c includes the particular library.
It's not necessary but sometimes makes the code easier to read. Most headers use soemthing like
#ifndef CCXX_MISC_H_ #define CCXX_MISC_H_
If I'm understanding E&S, what really matters is /Translation Unit/. When something is said to be in /file scope/ it refers to the file produced by the preprocessor. I'll have to confess, when my professor started talking about preprocessor directives in my C programming course, my head just started to spin. Now some of it seems to be falling into place.
...
#endif
It looks like Jerry Feldman has some insight into another twist on how this might affect preprocessing. Somehow, I suspect compilers are smart enough these days to know to skip the redundancies, but one never knows. And there may be still more subtle implications I have failed to comprehend in what he said.
so that if you #include the header more than once, after the first time, the preprocessor will just ignore the content of the header file.
Ho! Duh! Now I see what you're saying. I don't need to mess with putting the arcana at the top of my files, it's already there in the .h files. # So #including it more than once is not technically wrong ...
I personally tend to use #includes even where they're not needed just for readability: it's a way of saying this class needs something from misc.h even if it's not explicitly stated.
In Java, I usually import the class rather than the package, and typically use this.member whenever I can. I also tend to use ClassName.ststicMember, even within the class it is a member of. There's nothing that confuses me more than seeing an identifier arise from a completely obscure location. So I have to agree with your opinion.
Is this CommonC++ library really common? If I put it in my code and distribute it, will a bunch of people curse me? Is it the best bag of trick to draw from for general functionality such as string tokenization. I'm writing for a QT/KDE environment.
If there's something in QT that works better, I would use it on the grounds that the more class libraries you use, the greater the chance one won't compile. On the other hand CommonC++ is probably easier to get on any platform than Qt is.
Sadly, I didn't know about this class a couple of years' ago when I had to tokenise some input. It could have saved me some work and a buffer overrun.
After getting reasonably fluent in Java (I still have much to learn) I sat down to write some C. I was simply amazed at the result. I had forgotten all about iterating off the ends of arrays, and managing memory, etc. Fortunately, QT protects me from myself fairly well. Or so it would seem thus far.
-- JDL
I need to look this stuff over some more, but at a glance, it looks as though the Trolls have a different way to skin the same cat. This, for example, is something Java only wishes it had: http://doc.trolltech.com/3.1/qstring.html#insert And this looks to be a tokenizer, and then some: http://doc.trolltech.com/3.1/qstringlist.html http://doc.trolltech.com/3.1/qstring.html http://doc.trolltech.com/3.1/qstring-members.html STH
On Tue, 25 Mar 2003 21:57:12 -0500 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
I'll have to confess, when my professor started talking about preprocessor directives in my C programming course, my head just started to spin. Now some of it seems to be falling into place.
It looks like Jerry Feldman has some insight into another twist on how this might affect preprocessing. Somehow, I suspect compilers are smart enough these days to know to skip the redundancies, but one never knows. And there may be still more subtle implications I have failed to comprehend in what he said. (I teach C Programming at Northeastern :-). I am not aware of any C compiler than will try to skip redundancies.
In the old days, the C Preprocessor was a separate Unix utility, and is still available as a separate command:eg. cpp(1). Most modern C compilers actually combine the functions of the C Preprocessor with the lexer, but functionally it works the same. As John mentioned, most C and C++ header files contain something like: #ifndef CCXX_MISC_H_ #define CCXX_MISC_H_ ... #endif It is very important to understand the effects of the basic C Preprocessor functions. For example: #define MAX(x, y) ((x) > (y) ? (x) : (y)) Note that either x or y may be evaluated 2 times, and that x and y could be expressions and may side effect. Before the C89 standard, the c type "functions" (eg. ctype.h) were routinely implemented as macros. Today, the standard mandates that they be functions. Also, some stdio functions, such as getchar() are normally implemented as macros. You are also correct with translation unit. That is effectively what the compiler sees since the preprocessing procedure behaves as if it operated on the file before the compiler was executed. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
On Tue, 25 Mar 2003 10:45:05 -0500 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
I want to use the class described on the page found here on my SuSE 8.1. (It requiers the CommonC++ documentation to be installed.) file:///usr/share/doc/packages/CommonC++-doc/html/classost_1_1_string _tokenizer.html#_details
How would one typically (correctly) include such a library in his code? If I follow K&R 2nd. Ed., they put the #includes for libraries in any .c file that relies on them. Is that technically necessarily? From my experimentation, id doesn't /seem/ to be necessary. All that is required to get the code to run is that the one of the header files referenced in the .c includes the particular library.
I think you are mixing C and C++. K&R 2nd Ed. is ANSI 89 C, not c++. In general, most header files are set up with some protection from multiple inclusions as John Lamb mentioned. Also, in a properly written environment, header files should be self referencing, such that if you need some definition that is referenced by a header file and not directly by your C or C++ code, that header file should include the header files it depends on. Generally, header files include function prototypes, structure definitions, class definitions, et. al. If you have a c or c++ module, you only need to include those header files needed by that module. Libraries are different. Those are referenced at link time by the -l (lower case L) option. It is not a requirement in C that you prototype a function before it is used. But, C++ does require that. My rule of thumb is to include only what my module requires. But, others like to include everything that other modules in the project require. -- -- Gerald Feldman <gfeldman@attbi.com> Boston Computer Solutions and Consulting ICQ#156300 PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
On Tuesday 25 March 2003 06:46 pm, Jerry Feldman wrote:
On Tue, 25 Mar 2003 10:45:05 -0500
"Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
How would one typically (correctly) include such a library in his code? If I follow K&R 2nd. Ed., they put the #includes for libraries in any .c file that relies on them. Is that technically necessarily? From my experimentation, id doesn't /seem/ to be necessary. All that is required to get the code to run is that the one of the header files referenced in the .c includes the particular library.
I think you are mixing C and C++. K&R 2nd Ed. is ANSI 89 C, not c++.
I thought Bjarne Stroustrup did that. ;-)
Generally, header files include function prototypes, structure definitions, class definitions, et. al. If you have a c or c++ module, you only need to include those header files needed by that module.
I guess that is part of what I'm not clear on. From my perspective, the only code in a program outside of main() should, if at all possible, be contained in classes. If I accept that class definitions are properly placed in the header files, then I would only have main.cpp and a bunch of header files.
Libraries are different. Those are referenced at link time by the -l (lower case L) option.
I believe that merely tells the linker where to find the precompiled bits for the programming units referenced in your header files and your extern statements. I have to confess, I don't understand the whole process, especially regarding the extern specifier. If you do nm /opt/kde3-cvs/lib/libmcop.so You'll see a bunch of stuff like this: 000f405d t .L101 000f4070 t .L103 000f4083 t .L107 000f4096 t .L109 000f40a0 t .L113 000f40a7 t .L114 000f40ad t .L116 000f40b2 t .L117 000f40b8 t .L119 000f4117 t .L127 ... U time@@GLIBC_2.0 000f9fe0 t trim 000f97b0 t tryall_dlopen U uname@@GLIBC_2.0 U unlink@@GLIBC_2.0 000f9f70 t unload_deplibs 00115d40 d user_error_strings 00115d54 d user_search_path U vsprintf@@GLIBC_2.0 U write@@GLIBC_2.0 My understanding is this is a list of symbols mapping to address offsets within the compiled libraries. You may notice some of these are named with somewhat human sounding names. I /believe/ that is what maps the symbols you use in your code to the compiled form of the library code. If this is correct, the source code that was compiled to produce the library should have these names in it. There's often a corresponding .la file which seems to tell linkers to take the next fork in the road: # libmcop.la - a libtool library file # Generated by ltmain.sh - GNU libtool 1.4e (1.1090 2002/02/07 19:54:36) # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='libmcop.so.1' # Names of this library. library_names='libmcop.so.1.0.0 libmcop.so.1 libmcop.so' # The name of the static archive. old_library='' # Libraries that this one depends upon. dependency_libs=' -L/usr/X11R6/lib -L/usr/local/qt/lib -L/opt/kde3-cvs/lib / usr/lib/libgmodule-2.0.la /usr/lib/libgthread-2.0.la -lpthread /usr/lib/libg lib-2.0.la -ldl -L. -L/usr/lib/gcc-lib/i486-suse-linux/3.2 -L/usr/lib/gcc-li b/i486-suse-linux/3.2/../../../../i486-suse-linux/lib -L/usr/lib/gcc-lib/i48 6-suse-linux/3.2/../../.. /usr/lib/libstdc++.la -lm -lc -lgcc_s' # Version information for libmcop. current=1 age=0 revision=0 # Is this an already installed library? installed=yes # Files to dlopen/dlpreopen dlopen='' dlpreopen='' # Directory that this library needs to be installed in: libdir='/opt/kde3-cvs/lib'
It is not a requirement in C that you prototype a function before it is used. But, C++ does require that.
This is where things are sure to get confusing for me. Prototyping means something different in ECMAScript. Or at leas I believe it does. I wasn't able to find the actual term 'prototype' in E&S, but I do know it's used in other texts on C++. IIRC, what your statement means is that the symbol must be declared prior to its being referenced. I don't recall the rules for this, I will take your word for it. I simply assume that to be the case in any situation where I don't know what's going on. I learned that the hard way with JavaScript.
My rule of thumb is to include only what my module requires. But, others like to include everything that other modules in the project require.
I believe your approach is appropreate. Now all I need to do is figure out what _doesn't_ belong in a header file. ;-)
Gerald Feldman <gfeldman@attbi.com>
STH
On Tue, 25 Mar 2003 23:06:17 -0500 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
I thought Bjarne Stroustrup did that. ;-) He invented C++ and he also is an associate of Kernighan and Ritchie at Bell Labs.
I guess that is part of what I'm not clear on. From my perspective, the only code in a program outside of main() should, if at all possible, be contained in classes. If I accept that class definitions are properly placed in the header files, then I would only have main.cpp and a bunch of header files. Not so. Each class you define (in a header file) contains functions (I prefer to call them methods). Those functions may be inline (and expanded at instanciation time), but larger functions that are not inline should be defined in a source module. Whether a function should be inline or not depends on many factors. Additionally, it is not imperative that all functions in a C++ program be class members.
I think your comments on the linker are correct. I'm in a bit of a hurry. I'll respond to the rest of the email later. -- -- Gerald Feldman <gfeldman@attbi.com> Boston Computer Solutions and Consulting ICQ#156300 PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
On Wednesday 26 March 2003 07:51 am, Jerry Feldman wrote:
On Tue, 25 Mar 2003 23:06:17 -0500
"Steven T. Hatton" <hattons@globalsymmetry.com> wrote:
I thought Bjarne Stroustrup did that. ;-)
He invented C++ and he also is an associate of Kernighan and Ritchie at Bell Labs.
I like what he is reported to have said regarding the defining features of OOP. 'Object Oriented Programming is good, so if it's good, it's Object Oriented.'
Not so. Each class you define (in a header file) contains functions (I prefer to call them methods). Those functions may be inline (and expanded at instanciation time), but larger functions that are not inline should be defined in a source module.
As I suspected, /inline/ has a special meaning within C++. It has to do with how the method/function is dealt with on the activation stack. By default all methods declared within the class body are inline. Personally, I'm finding all this jumping back and forth between class.cpp and class.h rather burdensome, and I'm wondering why I should even do it. Why not just do everything within the class body and be done with it?
Whether a function should be inline or not depends on many factors.
I would like to hear your views on this. From my Java experience, it seems rather strange to define things about a class outside of the body.
Additionally, it is not imperative that all functions in a C++ program be class members.
This I understand. I just believe it is, in general, a bad idea.
-- Gerald Feldman <gfeldman@attbi.com>
STH
Steven T. Hatton wrote:
Personally, I'm finding all this jumping back and forth between class.cpp and class.h rather burdensome, and I'm wondering why I should even do it. Why not just do everything within the class body and be done with it?
Sometimes this makes sense. If the method finds the maximum of two integers, then I would put it in the class body because that's efficient. On the other hand, if the method reads an XML file and checks that it is valid, I would separate the definition from the declaration because the definition is sure to be very long and the method might be used in many subclasses. If I kept the definition in the class body, the object code would become very big because it would have many copies of the method rather than just one. Usually there's a tradeoff between speed and size. Small methods are best defined in the class body because the code runs faster (fewer function calls) but isn't much bigger. Big methods are best defined outside because the function call overhead is small compared to the work the function does and it reduces object code bloat (and makes the code compile faster).
Whether a function should be inline or not depends on many factors.
I would like to hear your views on this. From my Java experience, it seems rather strange to define things about a class outside of the body.
-- JDL
As I suspected, /inline/ has a special meaning within C++. It has to do with how the method/function is dealt with on the activation stack. By default all methods declared within the class body are inline. (I think you mean "defined" not "declared". A function that is defined within the scope of a class definition is inline by default. You can also define a function in a .cpp file and declare it as inline. Inline functions are expanded within the body of your source code when they are used. This may result in considerable code bloat. The advantage of inline is that an inline function is a bit faster than a non-inline function. Also, some C compilers may inline commong C library functions, such as strlen(). Additionally, static class variables must also be defined within the C++
On Fri, 28 Mar 2003 00:46:17 -0500 "Steven T. Hatton" <hattons@globalsymmetry.com> wrote: source file, not in the header file. I generally inline my constructors, destructors, and some of the overloaded operators, but if a function is more than a couple of lines, I generally do not inline it.
Additionally, it is not imperative that all functions in a C++ program be class members.
This I understand. I just believe it is, in general, a bad idea. Why do you think it is a bad idea. For the most part, I think that one should define classes properly, but there are always some cases where you may need or want a function that is not part of a class. This depends on the circumstances. One of the beauties of C++ is that it does not enforce object orientation. There are some circumstances where OO does not fit well. George Orwell once wrote "Break any of these rules sooner than say anything outright barbarous". This also applies to computer programming. I have always used the axiom that a program should be readable and maintainable. I have also written COBOL programs that were 90% assembler language (in old Burroughs systems). Sometimes the objective might be in conflict with the readability and maintainability axiom. One also must remember that C, C++ and Java are different languages with a common background. When writing code in one language, one should adapt one's coding style to that language. What is good for Java may not be good for C++ or vice-versa. -- -- Gerald Feldman <gfeldman@attbi.com> Boston Computer Solutions and Consulting ICQ#156300 PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
participants (4)
-
Jerry Feldman
-
John Lamb
-
Steve Zimmerman
-
Steven T. Hatton