Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #11892 > unrolled thread
| Started by | Christopher <cpisz@austin.rr.com> |
|---|---|
| First post | 2011-11-28 09:20 -0800 |
| Last post | 2011-11-30 09:23 +1300 |
| Articles | 20 on this page of 46 — 17 participants |
Back to article view | Back to comp.lang.c++
.h and .cpp Christopher <cpisz@austin.rr.com> - 2011-11-28 09:20 -0800
Re: .h and .cpp Leigh Johnston <leigh@i42.co.uk> - 2011-11-28 17:30 +0000
Re: .h and .cpp Christopher <cpisz@austin.rr.com> - 2011-11-28 10:39 -0800
Re: .h and .cpp Tobias Müller <troplin@bluewin.ch> - 2011-11-28 19:09 +0000
Re: .h and .cpp ralph <nt_consulting64@yahoo.net> - 2011-11-28 12:37 -0600
Re: .h and .cpp Christopher <cpisz@austin.rr.com> - 2011-11-28 10:48 -0800
Re: .h and .cpp ralph <nt_consulting64@yahoo.net> - 2011-11-28 14:24 -0600
Re: .h and .cpp yatremblay@bel1lin202.(none) (Yannick Tremblay) - 2011-11-30 11:24 +0000
Re: .h and .cpp Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-12-01 21:42 +0000
Re: .h and .cpp Rui Maciel <rui.maciel@gmail.com> - 2011-12-02 02:03 +0000
Re: .h and .cpp Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-12-02 20:59 +0000
Re: .h and .cpp "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-11-28 19:45 +0100
Re: .h and .cpp Leigh Johnston <leigh@i42.co.uk> - 2011-11-28 19:03 +0000
Re: .h and .cpp "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-11-28 20:36 +0100
Re: .h and .cpp Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-11-28 22:52 +0000
Re: .h and .cpp yatremblay@bel1lin202.(none) (Yannick Tremblay) - 2011-11-30 11:39 +0000
Re: .h and .cpp Juha Nieminen <nospam@thanks.invalid> - 2011-11-30 12:50 +0000
Re: .h and .cpp yatremblay@bel1lin202.(none) (Yannick Tremblay) - 2011-11-30 13:57 +0000
Re: .h and .cpp Juha Nieminen <nospam@thanks.invalid> - 2011-11-30 15:06 +0000
Re: .h and .cpp Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-11-30 16:21 +0000
Re: .h and .cpp Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-11-30 16:12 +0000
Re: .h and .cpp Goran <goran.pusic@gmail.com> - 2011-11-28 10:58 -0800
Re: .h and .cpp Christopher <cpisz@austin.rr.com> - 2011-11-28 13:30 -0800
Re: .h and .cpp Tobias Müller <troplin@bluewin.ch> - 2011-11-29 06:44 +0000
Re: .h and .cpp Goran <goran.pusic@gmail.com> - 2011-11-29 01:17 -0800
Re: .h and .cpp Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-11-30 00:53 -0800
Re: .h and .cpp "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-11-29 10:57 +0100
Re: .h and .cpp yatremblay@bel1lin202.(none) (Yannick Tremblay) - 2011-11-30 12:05 +0000
Re: .h and .cpp Rui Maciel <rui.maciel@gmail.com> - 2011-11-28 20:07 +0000
Re: .h and .cpp Geoff <geoff@invalid.invalid> - 2011-11-28 12:17 -0800
Re: .h and .cpp Ian Collins <ian-news@hotmail.com> - 2011-11-29 11:41 +1300
Re: .h and .cpp gwowen <gwowen@gmail.com> - 2011-11-29 07:37 -0800
Re: .h and .cpp Goran <goran.pusic@gmail.com> - 2011-11-29 00:08 -0800
Re: .h and .cpp Daniel <danielaparker@gmail.com> - 2011-11-29 08:31 -0800
Re: .h and .cpp ralph <nt_consulting64@yahoo.net> - 2011-11-29 14:49 -0600
Re: .h and .cpp Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-11-30 00:21 +0000
Re: .h and .cpp Andy Champ <no.way@nospam.invalid> - 2011-11-28 21:30 +0000
Re: .h and .cpp Paavo Helde <myfirstname@osa.pri.ee> - 2011-11-28 18:05 -0600
Re: .h and .cpp Paavo Helde <myfirstname@osa.pri.ee> - 2011-11-28 18:27 -0600
Re: .h and .cpp Juha Nieminen <nospam@thanks.invalid> - 2011-11-29 07:55 +0000
Re: .h and .cpp Christopher <cpisz@austin.rr.com> - 2011-11-29 12:15 -0800
Re: .h and .cpp Leigh Johnston <leigh@i42.co.uk> - 2011-11-29 20:19 +0000
Re: .h and .cpp Christopher <cpisz@austin.rr.com> - 2011-11-29 12:31 -0800
Re: .h and .cpp Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-11-30 00:31 +0000
Re: .h and .cpp Juha Nieminen <nospam@thanks.invalid> - 2011-11-30 09:43 +0000
Re: .h and .cpp Ian Collins <ian-news@hotmail.com> - 2011-11-30 09:23 +1300
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2011-11-30 16:12 +0000 |
| Message-ID | <slrnjdclf5.1bk.grahn+nntp@frailea.sa.invalid> |
| In reply to | #11976 |
On Wed, 2011-11-30, yatremblay@bel1lin202.(none) (Yannick Tremblay) wrote: > In article <slrnjd845a.1bk.grahn+nntp@frailea.sa.invalid>, > Jorgen Grahn <grahn+nntp@snipabacken.se> wrote: >>On Mon, 2011-11-28, Alf P. Steinbach wrote: >>> >>> For example, with Visual C++ use at least /W4, and with g++ use at least >>> -Wall >> >>I've mentioned it before, but IMHO -Wall is far from enough. I default >>to >> >>-Wall -Wextra -pedantic -std=c++98 -g -O3 > > You weakling! "Real Men" use: > > -Wall -Wextra -pedantic -std=c++98 -Weffc++ -Wold-style-cast -Werror > > :-) You have a point -- I include -Wold-style-cast these days, and I should really fix whatever Makefile I quoted from. (To non-g++ users: -Wold-style-cast means "warn for uses of C-style casts".) /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-11-28 10:58 -0800 |
| Message-ID | <72e0c6ca-1269-4e1d-9cf9-be78ec0c4584@y6g2000yqe.googlegroups.com> |
| In reply to | #11892 |
On Nov 28, 6:20 pm, Christopher <cp...@austin.rr.com> wrote: > If you were on a team of developers that had little C++ experience, > how would you go about explaining the reasoning as to why the > following rules should be followed? (Or why they shouldn't) > > 1) Class defintions go in their own .h (or .hpp for templates) file > named after the class Don't know about hpp for templates. It's *.h or *.hpp for everything if you ask me. If there is only one class ion the file, or if it's clearly the "main" class in it, then class_name.h is only natural. > 1a) Every class should have its own .h (or .hpp for templates) file Not so sure about that. All sorts of auxiliary artifacts can just as well be tagged along their principal stuff. > 1b) A .h file should never contain class implementation (except for > inline functions or methods) Purely mechanically, this doesn't work due to C compilation model: if the class parts are defined in a header, and said header is included in more than one translation unit (source file), linker will encounter duplicate symbols. > 2) Class implementations go in their own .cpp file (except for > templates) Same as above > 2a) A .cpp should never contain a class definition Disagreed. There's classes that will only be used in one translation unit. What can one gain by making another trivial header? > 3) One should not define multiple classes in a single .h file > 3a) Nested class defintions should be avoided without good reason > (what's good reason?) Good reason: nested class is used exclusively in context of the nesting class, possibly as a helper. Private nested classes should be avoided. They are better off in implementation file, as not to create additional compile-time dependency where there's no logical one. > 6) Variables should never be defined in a .h file Same as for classes - duplicate symbols galore. Exception: literal constants. If these are not constants, there should ideally be 0 of those in any given codebase. > 7) Globals should not be defined in a .h file I am not sure to understand the difference between a variable and a global? > 8) Every .cpp file should compile into a .obj file without error or > warning on its own. > i.e In Visual Studio, you should be able to right click a .cpp in > the source tree and choose compile, without error or warning in the > output. Except for precompiler header, which one should be using to save compilation time. IOW, if precompiled header is used and compiled, then any translation unit should compile. Otherwise, if you can't compile without errors, you can't compile, end of, so that's a given. As for warnings... When compiler emits a warning, it does it for a reason. Coder isn't smarter than compiler as far as formal verification goes. If there's a warning, coder should first try to change the code so that compiler has no reason for nagging. That usually ends in a better design. Casting or other compiler-gagging come distant second as idea. > Sadly, I find myself having to justify these things. Sadly is a good word. What, do directory entries cost these people money? > (of course > someone might point out I am wrong or exceptions to the above), but > these are things that I've always had drilled into my head throughout > the years and have rarely come acorss other developers that didn't do > the same. I am finding it frustrating to work on a project where 30 > classes defintions reside in the .h same .h file, a single .cpp file, > or worse a precompiled header. There is discussion, but I have to > explain reasoning. Ugh. That's a clear-cut sign that someone doesn't know how to work with C compilation model. Goran.
[toc] | [prev] | [next] | [standalone]
| From | Christopher <cpisz@austin.rr.com> |
|---|---|
| Date | 2011-11-28 13:30 -0800 |
| Message-ID | <6d8f5317-464d-4a34-92df-3986d9cc8e29@s4g2000yqk.googlegroups.com> |
| In reply to | #11898 |
On Nov 28, 12:58 pm, Goran <goran.pu...@gmail.com> wrote:
> > 1a) Every class should have its own .h (or .hpp for templates) file
>
> Not so sure about that. All sorts of auxiliary artifacts can just as
> well be tagged along their principal stuff.
I suppose a functor used for comparison might be an example. I need to
explain somehow what kinds of things would be an auxilary artifact
that is acceptable and what obviously requires seperation. I suppose
it is just intuitive to most of us.
I think what was said about nested classes is a good start. If the
class is only used by the main class in the file.
> > 1b) A .h file should never contain class implementation (except for
> > inline functions or methods)
>
> Purely mechanically, this doesn't work due to C compilation model: if
> the class parts are defined in a header, and said header is included
> in more than one translation unit (source file), linker will encounter
> duplicate symbols.
> > 2) Class implementations go in their own .cpp file (except for
> > templates)
>
> Same as above
>
I cannot visualize this scenario. Can you give a code example in which
any part of class implementation is required to be in the header,
excluding the use of templates?
Use of inclusion guards has always taken care of duplicate symbols
when a header is included in more than one source file and is pretty
standard practice in my experience.
> > 2a) A .cpp should never contain a class definition
>
> Disagreed. There's classes that will only be used in one translation
> unit. What can one gain by making another trivial header?
In this case, what's wrong with putting it in the header? I suppose
until I can visualize your argument for 1b and 2, I have trouble
seeing this as well.
When I see an unfamilair type in a source file, I would immeditaley
look in the corresponding .h file for its defintion. I'd hate to rely
on "not-so-intelli-sense" or something similar.
If inclusion guards are used, I don't see the down side.
> > 3) One should not define multiple classes in a single .h file
> > 3a) Nested class defintions should be avoided without good reason
> > (what's good reason?)
>
> Good reason: nested class is used exclusively in context of the
> nesting class, possibly as a helper.
Good reason!
> Private nested classes should be avoided. They are better off in
> implementation file, as not to create additional compile-time
> dependency where there's no logical one.
I could see this making sense pending more explanation to the previous
arguments.
> > 6) Variables should never be defined in a .h file
>
> Same as for classes - duplicate symbols galore. Exception: literal
> constants. If these are not constants, there should ideally be 0 of
> those in any given codebase.
Whoops, I believe I meant to say variable _declaration_. Definition
and Declaration seem to very confusing terms as they have different
meanings for classes and variables in C++.
What I mean is
int x = 10; should not appear in a .h file.
int x; However, may appear in a .h file, but I'd still argue that
there is probably a better way then using a global.
const int x = 10; Should not appear in a .h file
const int x; May appear in a .h file, but I'd rather see:
static int GetX() const
{
return 10;
}
because some other global MyClass might make use of x and then I run
into the static intialization fiasco.
or better if only used in one class:
class WhereXIsUsed
{
public:
private:
const int m_x;
};
or possibly something like
struct SystemConfigurationDefaults
{
const int m_x;
};
> > 7) Globals should not be defined in a .h file
>
> I am not sure to understand the difference between a variable and a
> global?
One is a superset of the other.
But again, I think I meant declared instead.
> > 8) Every .cpp file should compile into a .obj file without error or
> > warning on its own.
> > i.e In Visual Studio, you should be able to right click a .cpp in
> > the source tree and choose compile, without error or warning in the
> > output.
>
> Except for precompiler header, which one should be using to save
> compilation time. IOW, if precompiled header is used and compiled,
> then any translation unit should compile.
When it comes to precompiled headers, what I am trying to convey is
that everything should compile without them.
Precomiled headers should be used as a build optimization only, if at
all, and not as part of the implementation.
How I've been doing it:
---
/*
* foo.h
*/
#ifndef FOO_H
#define FOO_H
#include <iostream>
// Use of iostream
// SNIP
#endif
---
/*
* foo.cpp
*/
#include "precompiled-header.h"
#include "foo.h"
#include <algorithm>
// Use of algorithm
//SNIP
---
/*
* precompiled-header.h
*/
#include <algorithm>
#include <iostream>
// SNIP
Allows for foo.obj regardless of whether or not the precompiled header
was compiled. If the pre-compiled header was used, it speeds up build
time in some scenarios.
What I've come across that I believe is incorrect, but still compiles
if build order happens to work out:
---
/*
* foo.h
*/
#ifndef FOO_H
#define FOO_H
// Use of iostream
// SNIP
#endif
---
/*
* foo.cpp
*/
#include "precompiled-header.h"
// Use of algorithm
//SNIP
---
/*
* precompiled-header.h
*/
#include "foo.h"
#include <algorithm>
#include <iostream>
// SNIP
My difficulty, assuming I am correct (because I am totally willing to
accept correction with explanation), is expressing this in words.
> Sadly is a good word. What, do directory entries cost these people
> money?
I've heard words like "complexity" and "clutter"
Ironic, because I use words like "simple" and "logical"
[toc] | [prev] | [next] | [standalone]
| From | Tobias Müller <troplin@bluewin.ch> |
|---|---|
| Date | 2011-11-29 06:44 +0000 |
| Message-ID | <55349412344240394.082701troplin-bluewin.ch@news.aioe.org> |
| In reply to | #11910 |
Christopher <cpisz@austin.rr.com> wrote: > Use of inclusion guards has always taken care of duplicate symbols > when a header is included in more than one source file and is pretty > standard practice in my experience. Inclusion guards don't help you here, at least if you have more than one translation unit. Inclusion guards make sure that you don't have duplicate class definitions in one TU. However, every header file needs to be visible in every TU or else you can't use the classes defined in that header. And if you have method implementations in the header, the code will be generated in every TU and evetually the linker will complain (not the compiler). Tobi
[toc] | [prev] | [next] | [standalone]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-11-29 01:17 -0800 |
| Message-ID | <b2b7ea80-4d21-4ab3-a6a6-3f8d50350ddf@s4g2000yqk.googlegroups.com> |
| In reply to | #11910 |
On Nov 28, 10:30 pm, Christopher <cp...@austin.rr.com> wrote:
> On Nov 28, 12:58 pm, Goran <goran.pu...@gmail.com> wrote:
>
> > > 1a) Every class should have its own .h (or .hpp for templates) file
>
> > Not so sure about that. All sorts of auxiliary artifacts can just as
> > well be tagged along their principal stuff.
>
> I suppose a functor used for comparison might be an example. I need to
> explain somehow what kinds of things would be an auxilary artifact
> that is acceptable and what obviously requires seperation. I suppose
> it is just intuitive to most of us.
>
> I think what was said about nested classes is a good start. If the
> class is only used by the main class in the file.
>
> > > 1b) A .h file should never contain class implementation (except for
> > > inline functions or methods)
>
> > Purely mechanically, this doesn't work due to C compilation model: if
> > the class parts are defined in a header, and said header is included
> > in more than one translation unit (source file), linker will encounter
> > duplicate symbols.
> > > 2) Class implementations go in their own .cpp file (except for
> > > templates)
>
> > Same as above
>
> I cannot visualize this scenario. Can you give a code example in which
> any part of class implementation is required to be in the header,
> excluding the use of templates?
I poorly expressed myself? When I said "same as above", I meant "you
have to put class implementation in it's own implementation because
otherwise linker encounters duplicate symbols". So class
implementations absolutely must go in an implementation file. Perhaps
it's own implementation file (e.g. small related thingy can tag
along).
>
> Use of inclusion guards has always taken care of duplicate symbols
> when a header is included in more than one source file and is pretty
> standard practice in my experience.
>
> > > 2a) A .cpp should never contain a class definition
>
> > Disagreed. There's classes that will only be used in one translation
> > unit. What can one gain by making another trivial header?
>
> In this case, what's wrong with putting it in the header? I suppose
> until I can visualize your argument for 1b and 2, I have trouble
> seeing this as well.
If code artifact is used in only one translation unit, it does not
require a header, that's all. Make it if you wish, but it's only more
files to go around.
> When I see an unfamilair type in a source file, I would immeditaley
> look in the corresponding .h file for its defintion. I'd hate to rely
> on "not-so-intelli-sense" or something similar.
What's wrong with grep or "Find in files" in VS?
> If inclusion guards are used, I don't see the down side.
>
> > > 3) One should not define multiple classes in a single .h file
> > > 3a) Nested class defintions should be avoided without good reason
> > > (what's good reason?)
>
> > Good reason: nested class is used exclusively in context of the
> > nesting class, possibly as a helper.
>
> Good reason!
>
> > Private nested classes should be avoided. They are better off in
> > implementation file, as not to create additional compile-time
> > dependency where there's no logical one.
>
> I could see this making sense pending more explanation to the previous
> arguments.
>
> > > 6) Variables should never be defined in a .h file
>
> > Same as for classes - duplicate symbols galore. Exception: literal
> > constants. If these are not constants, there should ideally be 0 of
> > those in any given codebase.
>
> Whoops, I believe I meant to say variable _declaration_. Definition
> and Declaration seem to very confusing terms as they have different
> meanings for classes and variables in C++.
>
> What I mean is
> int x = 10; should not appear in a .h file.
That doesn't work anyhow. For example (it's the example you're asking
for elsewhere, too), you can compile (BUT NOT LINK)
h.h
#ifndef whatever
#define whatever
int x=10;
#endif
s.cpp
#include "h.h"
void f()
{
x++;
}
main.cpp
#include "h.h"
int main(int, const char*[])
{
x++
}
> int x; However, may appear in a .h file, but I'd still argue that
> there is probably a better way then using a global.
I like
extern int x;
(explains the intent better IMO)
> const int x = 10; Should not appear in a .h file
> const int x; May appear in a .h file, but I'd rather see:
>
> static int GetX() const
> {
> return 10;
>
> }
>
> because some other global MyClass might make use of x and then I run
> into the static intialization fiasco.
>
> or better if only used in one class:
>
> class WhereXIsUsed
> {
> public:
> private:
> const int m_x;
>
> };
If only used in one class, it's best declared in class's
implementation. That's (for me) to avoid compile-time dependency: you
can change it in *.cpp all you like, you don't recompile all other
*.cpp-s that include your_class.h
>
> or possibly something like
>
> struct SystemConfigurationDefaults
> {
> const int m_x;
>
> };
> > > 7) Globals should not be defined in a .h file
>
> > I am not sure to understand the difference between a variable and a
> > global?
>
> One is a superset of the other.
> But again, I think I meant declared instead.
>
> > > 8) Every .cpp file should compile into a .obj file without error or
> > > warning on its own.
> > > i.e In Visual Studio, you should be able to right click a .cpp in
> > > the source tree and choose compile, without error or warning in the
> > > output.
>
> > Except for precompiler header, which one should be using to save
> > compilation time. IOW, if precompiled header is used and compiled,
> > then any translation unit should compile.
>
> When it comes to precompiled headers, what I am trying to convey is
> that everything should compile without them.
> Precomiled headers should be used as a build optimization only, if at
> all, and not as part of the implementation.
Yes, agreed.
> How I've been doing it:
>
> ---
> /*
> * foo.h
> */
> #ifndef FOO_H
> #define FOO_H
>
> #include <iostream>
>
> // Use of iostream
> // SNIP
> #endif
>
> ---
> /*
> * foo.cpp
> */
> #include "precompiled-header.h"
> #include "foo.h"
>
> #include <algorithm>
>
> // Use of algorithm
> //SNIP
>
> ---
> /*
> * precompiled-header.h
> */
> #include <algorithm>
> #include <iostream>
> // SNIP
>
> Allows for foo.obj regardless of whether or not the precompiled header
> was compiled. If the pre-compiled header was used, it speeds up build
> time in some scenarios.
Actually, I like that. I was wrong when I said that you can build
"provided that precompiled header was built before" (and you are
right).
Goran.
[toc] | [prev] | [next] | [standalone]
| From | Nick Keighley <nick_keighley_nospam@hotmail.com> |
|---|---|
| Date | 2011-11-30 00:53 -0800 |
| Message-ID | <d89a97ce-ec8f-411d-b902-3c7f840a34b7@n10g2000vbg.googlegroups.com> |
| In reply to | #11910 |
On Nov 28, 9:30 pm, Christopher <cp...@austin.rr.com> wrote:
> On Nov 28, 12:58 pm, Goran <goran.pu...@gmail.com> wrote:
<snip>
> > > 1b) A .h file should never contain class implementation (except for
> > > inline functions or methods)
>
> > Purely mechanically, this doesn't work due to C compilation model: if
> > the class parts are defined in a header, and said header is included
> > in more than one translation unit (source file), linker will encounter
> > duplicate symbols.
>
> > > 2) Class implementations go in their own .cpp file (except for
> > > templates)
>
> > Same as above
>
> I cannot visualize this scenario. Can you give a code example in which
> any part of class implementation is required to be in the header,
> excluding the use of templates?
>
> Use of inclusion guards has always taken care of duplicate symbols
> when a header is included in more than one source file and is pretty
> standard practice in my experience.
not if it's in two different compilation units. The key thing is "if
the class parts are /defined/ in a header" (emp. mine). In a nutshell
a declaration of an object (this probably applies to non-objects like
functions as well) says "this is the name of something- but doesn't
allocate any space" whilst a definition gives it soemwhere to live.
Naming something more than once is ok. Creating more than one copy of
something is wrong. This is sometimes referred to as The One
Definition Rule.
> > > 2a) A .cpp should never contain a class definition
>
> > Disagreed. There's classes that will only be used in one translation
> > unit. What can one gain by making another trivial header?
>
> In this case, what's wrong with putting it in the header? I suppose
> until I can visualize your argument for 1b and 2, I have trouble
> seeing this as well.
I'd say don't put it in a header if you don'e need to. It's just work.
<snip>
> > > 6) Variables should never be defined in a .h file
>
> > Same as for classes - duplicate symbols galore. Exception: literal
> > constants. If these are not constants, there should ideally be 0 of
> > those in any given codebase.
>
> Whoops, I believe I meant to say variable _declaration_. Definition
> and Declaration seem to very confusing terms as they have different
> meanings for classes and variables in C++.
>
> What I mean is
> int x = 10; should not appear in a .h file.
> int x; However, may appear in a .h file, but I'd still argue that
> there is probably a better way then using a global.
"global" isn't really a C++ term. ITYM "external". If you are using
them then declare 'em external.
// externals.h
int x;
// externals.c
#include "externals.h"
int x = 10;
// user.c
#include "externals.h"
void f()
{
doThing (x);
}
> const int x = 10; Should not appear in a .h file
> const int x; May appear in a .h file, but I'd rather see:
>
> static int GetX() const
> {
> return 10;
>
> }
that should be inline
> because some other global MyClass might make use of x and then I run
> into the static intialization fiasco.
really? This surprises me. Are const items of basic types really
subject to SIF? I thought declaring consts in a header was ok.
const double PI = 3.1415926535;
I thought the idea was to be able to replace C's
# define PI 3.1415926535
to have to hide it in a static function seems really icky. I tghink
I'll start using #define again...
> or better if only used in one class:
>
> class WhereXIsUsed
> {
> public:
> private:
> const int m_x;
>
> };
>
> or possibly something like
>
> struct SystemConfigurationDefaults
> {
> const int m_x;
>
> };
namespaces maybe?
> > > 7) Globals should not be defined in a .h file
>
> > I am not sure to understand the difference between a variable and a
> > global?
>
> One is a superset of the other.
> But again, I think I meant declared instead.
you also need to expalin what a "global" is. The term is not terribly
well defined.
<snip>
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2011-11-29 10:57 +0100 |
| Message-ID | <jb2aa1$g0$1@dont-email.me> |
| In reply to | #11898 |
On 28.11.2011 19:58, Goran wrote: > On Nov 28, 6:20 pm, Christopher<cp...@austin.rr.com> wrote: > >> 1b) A .h file should never contain class implementation (except for >> inline functions or methods) > > Purely mechanically, this doesn't work due to C compilation model: if > the class parts are defined in a header, and said header is included > in more than one translation unit (source file), linker will encounter > duplicate symbols. I think the above is perhaps too vaguely expressed. First, a "class definition" does not necessarily include definitions of member functions. Secondly, it's quite common to put also definitions of member functions in a header. They need then to be either templates or `inline`. For example, many Boost sub-libraries are header only. Cheers & hth., - Alf
[toc] | [prev] | [next] | [standalone]
| From | yatremblay@bel1lin202.(none) (Yannick Tremblay) |
|---|---|
| Date | 2011-11-30 12:05 +0000 |
| Message-ID | <jb5674$o4u$1@dont-email.me> |
| In reply to | #11898 |
In article <72e0c6ca-1269-4e1d-9cf9-be78ec0c4584@y6g2000yqe.googlegroups.com>,
Goran <goran.pusic@gmail.com> wrote:
>On Nov 28, 6:20 pm, Christopher <cp...@austin.rr.com> wrote:
>> If you were on a team of developers that had little C++ experience,
>> how would you go about explaining the reasoning as to why the
>> following rules should be followed? (Or why they shouldn't)
>>
>> 1) Class defintions go in their own .h (or .hpp for templates) file
>> named after the class
>
>Don't know about hpp for templates. It's *.h or *.hpp for everything
>if you ask me. If there is only one class ion the file, or if it's
>clearly the "main" class in it, then class_name.h is only natural.
Maintainability: if the general rule that each class "class_name" is
defined in class_name.h and implemented in class_name.cpp, navigating
the code is easier than if 7 different classes are defined in file1.h
and randomly implemented in file2.cpp and file3.cpp and some additonal
classes are defined and implemented entirely in file3.cpp
>> 2a) A .cpp should never contain a class definition
>
>Disagreed. There's classes that will only be used in one translation
>unit. What can one gain by making another trivial header?
I don't entirely disgree with you. but in large project, this can be a
valid policy.
Typically, what will happen is devA decides he needs a little helper
class for his big class, he knows he only needs it here in this
specific translation unit so just define and implement it fully inside
big_class.cpp.
Then often, devB, who is implementing another_class, needs some helper
functionality. It's fairly generic functionality so he peeks in the
generic area for a header file that might indicate that this
functionality is already available. He doesn't see anything so he
implements my_helper_class inside another_class.cpp ith functionality
almost to same as that implemented by devA previously.
Then so on for DevC, DevD ...
If you are lucky, maybe DevE actually finds the implemention that
exists in big_class.cpp and figure out that he should reuse it rather
than duplicate the functionality. Unfortunately, for him to reuse it,
he now has to extract first_helper out of big_class.cpp, create
first_helper.h and first_helper.cpp.
If instead DevA wrote first_helper in its own files, any future reuse
would have been much easier.
In a previous life, I once searched through the code base of a large-ish
C project and found something like 4-5 different implementation of a
XML-quoting function, all of them defined and implemented locally.
Then there's unit testing: if your class is only defined inside a a
cpp file, it's rather difficult to unit test it.
>
>> 8) Every .cpp file should compile into a .obj file without error or
>> warning on its own.
>> i.e In Visual Studio, you should be able to right click a .cpp in
>> the source tree and choose compile, without error or warning in the
>> output.
More important in my opinion:
For every header file the following should compile without error or
warning:
#include "the_header.h"
int main() { return 0; }
if you need to preceed #include "the_header.h" by anything, your
header file is not self contained and should be fixed.
Yannick
[toc] | [prev] | [next] | [standalone]
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2011-11-28 20:07 +0000 |
| Message-ID | <jb0pmf$fn$1@speranza.aioe.org> |
| In reply to | #11892 |
Christopher wrote: > If you were on a team of developers that had little C++ experience, > how would you go about explaining the reasoning as to why the > following rules should be followed? (Or why they shouldn't) > > 1) Class defintions go in their own .h (or .hpp for templates) file > named after the class > 1a) Every class should have its own .h (or .hpp for templates) file > 1b) A .h file should never contain class implementation (except for > inline functions or methods) > > 2) Class implementations go in their own .cpp file (except for > templates) > 2a) A .cpp should never contain a class definition > > 3) One should not define multiple classes in a single .h file > 3a) Nested class defintions should be avoided without good reason > (what's good reason?) > > 6) Variables should never be defined in a .h file > 7) Globals should not be defined in a .h file > 8) Every .cpp file should compile into a .obj file without error or > warning on its own. > i.e In Visual Studio, you should be able to right click a .cpp in > the source tree and choose compile, without error or warning in the > output. > ---- > > Sadly, I find myself having to justify these things. (of course > someone might point out I am wrong or exceptions to the above), but > these are things that I've always had drilled into my head throughout > the years and have rarely come acorss other developers that didn't do > the same. I am finding it frustrating to work on a project where 30 > classes defintions reside in the .h same .h file, a single .cpp file, > or worse a precompiled header. There is discussion, but I have to > explain reasoning. Separating declarations from implementations and mandating that each class should be defined and implemented in separate source files are a couple of practices which help track what changes were made to each individual component and who made those changes. With this, auditing the code becomes a bit simpler. This practice also reduces the amount of potential merging conflicts any commit might induce. Rui Maciel
[toc] | [prev] | [next] | [standalone]
| From | Geoff <geoff@invalid.invalid> |
|---|---|
| Date | 2011-11-28 12:17 -0800 |
| Message-ID | <0qq7d7dttuhi1fll7hvf0gqfk5n90u29o0@4ax.com> |
| In reply to | #11892 |
I disagree with your rule 6. It precludes #define. Also, rule number 6: there is no rule 6! (Obligatory Monty Python reference.) For some very interesting coding standards referenced by no less authority than Stroustrup himself: http://www2.research.att.com/~bs/JSF-AV-rules.pdf via his page: http://www2.research.att.com/~bs/C++.html
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-11-29 11:41 +1300 |
| Message-ID | <9jih16F4d0U24@mid.individual.net> |
| In reply to | #11905 |
On 11/29/11 09:17 AM, Geoff wrote: > I disagree with your rule 6. It precludes #define. Which was "Variables should never be defined in a .h file". Context is good. Why would you be using #define for variables in C++? -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-11-29 07:37 -0800 |
| Message-ID | <aa2bf9ff-f6c5-4de7-a9ac-3e5c29c3668a@q16g2000yqn.googlegroups.com> |
| In reply to | #11913 |
On Nov 28, 10:41 pm, Ian Collins <ian-n...@hotmail.com> wrote: > On 11/29/11 09:17 AM, Geoff wrote: > > > I disagree with your rule 6. It precludes #define. > > Which was "Variables should never be defined in a .h file". Context is > good. > > Why would you be using #define for variables in C++? In a header, you may want some C/C++ cross compatibility and the C definition of what counts as a compile-time constant can make it the least-unpleasant way to define a constant. romanes.h: ------------------------ const size_t NROMANS = 512; #define HOWMANYROMANS 512 romanes.c ----------------- static int[NFOO]; /* D'oh! Won't compile as C */ static int[HOWMANYROMANS]; /* Will compile as C*/
[toc] | [prev] | [next] | [standalone]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-11-29 00:08 -0800 |
| Message-ID | <f48446b8-ddb7-4e35-bad6-04f129a21d80@u5g2000vbd.googlegroups.com> |
| In reply to | #11905 |
On Nov 28, 9:17 pm, Geoff <ge...@invalid.invalid> wrote: > I disagree with your rule 6. It precludes #define. > > Also, rule number 6: there is no rule 6! > (Obligatory Monty Python reference.) > > For some very interesting coding standards referenced by no less > authority than Stroustrup himself: > > http://www2.research.att.com/~bs/JSF-AV-rules.pdf > > via his page:http://www2.research.att.com/~bs/C++.html +1. This is "C++ for embedded systems bible" IMHO. Goran.
[toc] | [prev] | [next] | [standalone]
| From | Daniel <danielaparker@gmail.com> |
|---|---|
| Date | 2011-11-29 08:31 -0800 |
| Message-ID | <0872fe37-4a78-4947-b637-8363b51d270c@g21g2000yqc.googlegroups.com> |
| In reply to | #11905 |
On Nov 28, 3:17 pm, Geoff <ge...@invalid.invalid> wrote: > For some very interesting coding standards referenced by no less > authority than Stroustrup himself: > > http://www2.research.att.com/~bs/JSF-AV-rules.pdf > Interesting to see the recommended naming conventions, Example_class_name RGB_colors example_function_name Underscores don't seem to be that popular though, more likely to be seen are ExampleClassName, RGBColors or RgbColors, and exampleFunctionName. Daniel
[toc] | [prev] | [next] | [standalone]
| From | ralph <nt_consulting64@yahoo.net> |
|---|---|
| Date | 2011-11-29 14:49 -0600 |
| Message-ID | <71gad7p4tapl8t5n3g43dj55lrka5i2kco@4ax.com> |
| In reply to | #11957 |
On Tue, 29 Nov 2011 08:31:55 -0800 (PST), Daniel <danielaparker@gmail.com> wrote: >On Nov 28, 3:17 pm, Geoff <ge...@invalid.invalid> wrote: >> For some very interesting coding standards referenced by no less >> authority than Stroustrup himself: >> >> http://www2.research.att.com/~bs/JSF-AV-rules.pdf >> >Interesting to see the recommended naming conventions, > >Example_class_name > >RGB_colors > >example_function_name > >Underscores don't seem to be that popular though, more likely to be >seen are ExampleClassName, RGBColors or RgbColors, and >exampleFunctionName. > >Daniel What you are describing is called Camel Case or Camelback. Most historians trace its use as a direct migration from using inner underscores as a delimiter to using uppercase to separate words. Mostly because it saved space and yet still provides readability. Underscores were popular in the early days of C and C++, and it is just that popularity that has led to discouraging their use. So many libraries and implementations used underscores - collisions were inevitable. ANSI now forbids them in some contexts. However, it might be useful to remember before posting that there are three subjects that are best avoided in this newsgroup: 1) Favorite Editors, 2) Indent Styles, 3) and Naming Conventions -ralph <bg> [*Comments should receive honorable mention.]
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2011-11-30 00:21 +0000 |
| Message-ID | <slrnjdatok.1bk.grahn+nntp@frailea.sa.invalid> |
| In reply to | #11962 |
On Tue, 2011-11-29, ralph wrote: > On Tue, 29 Nov 2011 08:31:55 -0800 (PST), Daniel > <danielaparker@gmail.com> wrote: > >>On Nov 28, 3:17 pm, Geoff <ge...@invalid.invalid> wrote: >>> For some very interesting coding standards referenced by no less >>> authority than Stroustrup himself: >>> >>> http://www2.research.att.com/~bs/JSF-AV-rules.pdf >>> >>Interesting to see the recommended naming conventions, >> >>Example_class_name >> >>RGB_colors >> >>example_function_name >> >>Underscores don't seem to be that popular though, more likely to be >>seen are ExampleClassName, RGBColors or RgbColors, and >>exampleFunctionName. >> >>Daniel > > What you are describing is called Camel Case or Camelback. Most > historians trace its use as a direct migration from using inner > underscores as a delimiter to using uppercase to separate words. > Mostly because it saved space and yet still provides readability. > > Underscores were popular in the early days of C and C++, and it is > just that popularity that has led to discouraging their use. Underscores is still my main style, for function and variable names. It's also the style for the Linux kernel and many Unix utilities. I suspect under_score is simply an old Unix convention. Most other OSes seem to use some CamelCase variant. (Happily, none that I know of uses ALL_UPPERCASE as the main style.) > So many > libraries and implementations used underscores - collisions were > inevitable. That doesn't make sense -- you cannot invent a new naming convention for each library! Prefixes is the way it's done, pre-namespaces at least. > ANSI now forbids them in some contexts. > > However, it might be useful to remember before posting that there are > three subjects that are best avoided in this newsgroup: > 1) Favorite Editors, > 2) Indent Styles, > 3) and Naming Conventions Yes, but we're ok as long as there's no advocacy involved. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | Andy Champ <no.way@nospam.invalid> |
|---|---|
| Date | 2011-11-28 21:30 +0000 |
| Message-ID | <yPednYfPns34YE7TnZ2dnUVZ8iWdnZ2d@eclipse.net.uk> |
| In reply to | #11892 |
On 28/11/2011 17:20, Christopher wrote: > If you were on a team of developers that had little C++ experience, > how would you go about explaining the reasoning as to why the > following rules should be followed? (Or why they shouldn't) "Because I've been doing it for years and it works. Here are a couple of standard texts that advise something similar. You might have occasions for breaking these ***guidelines*** - if you do, talk to me first". But that said... > > 1) Class defintions go in their own .h (or .hpp for templates) file > named after the class We never use .hpp files. > 1a) Every class should have its own .h (or .hpp for templates) file This is a guideline only. As an example - I've recently added a new .h file to our code which contains 4 pure virtual class definitions - they'd be interfaces if C++ supported such a thing. They're to support a similar function in 4 other classes. The reason they are there is that the 4 ought to look similar - they are handling error cases as we serialise a data set into an object model. Each one has a method or two similar to virtual variabletype GetAbsentothertype(const unsigned index) = 0; where variabletype & othertype differ. I realised that different people were implementing "GetAbsent", "CreateAbsent", "FindAbsent"... and this keeps the unrelated functions looking similar. It has no other purpose. > 1b) A .h file should never contain class implementation (except for > inline functions or methods) As we never use .hpp files... > > 2) Class implementations go in their own .cpp file (except for > templates) > 2a) A .cpp should never contain a class definition Locally used helper classes can happily be hidden away inside a .cpp file. > > 3) One should not define multiple classes in a single .h file > 3a) Nested class defintions should be avoided without good reason > (what's good reason?) An example: A class is a specialised container for a collection of some other type. There's a helper for the sort order that's used for nothing else. Hiding it inside the class where it's obvious that it is associated can make sense (sometimes!) and reduces the pollution of your namespace. > > 6) Variables should never be defined in a .h file What do you mean by variables? Obviously not class members... > 7) Globals should not be defined in a .h file ... and apparently not globals. But let me stretch that rule. "Globals should not be". If they must, then they should normally "be defined in a .h file". > 8) Every .cpp file should compile into a .obj file without error or > warning on its own. > i.e In Visual Studio, you should be able to right click a .cpp in > the source tree and choose compile, without error or warning in the > output. Be careful on warnings. Visual Studio will throw warnings at level 4 on the standard Microsoft headers. We have a few that come out on level 3 that we can't get rid of without disabling the warning globally. But on the errors, agree 100%. <snip> As someone said upthread "There is no rule 6". Look on them as guidelines, which can be broken occasionally. They are here to help, not hinder. Andy
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2011-11-28 18:05 -0600 |
| Message-ID | <Xns9FAC154E73B4Dmyfirstnameosapriee@216.196.109.131> |
| In reply to | #11892 |
Christopher <cpisz@austin.rr.com> wrote in news:d30834a8-3bf4-49a4-b1eb- b66aef965475@i8g2000vbh.googlegroups.com: > 8) Every .cpp file should compile into a .obj file without error or > warning on its own. > i.e In Visual Studio, you should be able to right click a .cpp in > the source tree and choose compile, without error or warning in the > output. This goes against the practice of putting platform-specific code in separate .cpp files (which can share a common cross-platform .h file). One cannot and should not be able to compile Linux-specific .cpp-s on Windows, or vice versa. Including all these Linux-specific .cpp-s in the Visual Studio projects is a good idea though as then they become easily greppable (Shift-Ctrl-F). They should however be marked as "Exclude from build". I have never tried if right-click-compile works on such a file... nope, Compile is grayed out. That's how it should be. Also, avoiding all warnings at any cost might be counter-productive. The unimportant warnings should be fixed or suppressed only if they start to hinder finding other (important) errors or warnings in the compiler output. cheers Paavo
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2011-11-28 18:27 -0600 |
| Message-ID | <Xns9FAC18F41BB6Fmyfirstnameosapriee@216.196.109.131> |
| In reply to | #11892 |
Christopher <cpisz@austin.rr.com> wrote in news:d30834a8-3bf4-49a4-b1eb- b66aef965475@i8g2000vbh.googlegroups.com: > the same. I am finding it frustrating to work on a project where 30 > classes defintions reside in the .h same .h file, a single .cpp file, > or worse a precompiled header. There are always exceptions, so such rules cannot be made absolute. The first rule should be that any rule can be broken if justified. The one-class-per-cpp rule is good so far as you have few classes. If you have hundreds or thousands of them, then looking them up in the file listings starts to be cumbersome. Searching-grepping is more scalable, but then it will not be so important any more if the classes are in separate files or not. For example, in our codebase there are many C++ classes which define modules (essentially commands) for a scripting language. These classes are registered by the scripting language interpreter, otherwise they are not needed for any other code, so there is no reason to put the class definitions in the header file. Also, the classes are typically quite short, which would make it cumbersome to put each class in a separate .cpp file. Besides, it would make the registration mechanism much more awkward. So there are a lot of such classes in the same .cpp file (as much as 96, 88 and 63 in some .cpp files). Yeah, maybe this is a bit too much, but I do not believe that putting all these into hundreds of separate .cpp files would make anything better. Cheers Paavo
[toc] | [prev] | [next] | [standalone]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2011-11-29 07:55 +0000 |
| Message-ID | <4ed48fde$0$2782$7b1e8fa0@news.nbl.fi> |
| In reply to | #11892 |
Christopher <cpisz@austin.rr.com> wrote: > 1) Class defintions go in their own .h (or .hpp for templates) file > named after the class I never use ".h" as a file name extension for C++ headers for a rather obvious reason: It's not C code and I want to distinguish C code from C++ code unambiguously. Also, I don't see why headers containing templated code should be named differently from headers that don't. From unix I am accustomed to using .cc and .hh extensions, but that's another story. > 1a) Every class should have its own .h (or .hpp for templates) file You are polluting the global namespace this way for classes that could well be compilation-unit-local. Such classes should go into a nameless namespace, which is incompatible with a public header file. (Ok, technically speaking you can put a nameless namespace in a header file because, after all, it's just C++ code like everything else, but the advantage of doing this is dubious. You will only be including it in the compilation unit where it's used, and including it anywhere else would be useless, as it would only define an unimplemented local class.) You might have learned otherwise, but I have learned that public interfaces should be as minimal as possible, and polluting the global namespace with local types is not good design. > 1b) A .h file should never contain class implementation (except for > inline functions or methods) That's a null statement. If a header file contains implementations, they will be inline by necessity (else you'll get linker errors if the header is included more than once), so that rule isn't really saying anything. Perhaps if you had said: "A header file should contain inline function implementations only if there's a very good reason for them. Otherwise they should go to the correspondent compilation unit." > 2) Class implementations go in their own .cpp file (except for > templates) Technically speaking templates can be declared in a header file and implemented in a compilation unit even in cases where the template is used somewhere else besides that compilation unit (yes, even without support for export; it can be done with explicit template instantiation), but that's not a usual circumstance. But I digress. > 2a) A .cpp should never contain a class definition Why not? If a class is used only in that one compilation unit, and especially if it's small, what's the problem? Think about this: What would be the difference between a private inner class and a class local to the compilation unit (ie. in a nameless namespace), except for scope? Would the former be ok but not the latter? Why? (The testability argument doesn't hold because you cannot test a private inner class from the outside.) (And please don't tell me you oppose private inner classes too.) > 3) One should not define multiple classes in a single .h file If two classes are relatively small and strongly related to one other, why not? A typical example would be a template class and a specialization for a specific template type. If you put them in separate header files, you would have a small problem in what to include. There are many non-templated examples as well. > 3a) Nested class defintions should be avoided without good reason > (what's good reason?) I don't see why inner classes "should be avoided". In general class design should be as simple as possible. That includes, among many other things, minimizing the amount of inner classes. However, there's nothing special about them in particular that should be avoided. Iterators are good examples of public inner classes. Why should they be avoided? And if some private implementation of the class needs a private class, then why not? (In fact, sometimes trying to religiously avoid inner classes can make your code much more complicated and harder to manage.) > 6) Variables should never be defined in a .h file There are some situations where extern variables are justified. Although even in those cases they should usually be declared inside a namespace to minimize global namespace pollution. (std::cout would be an example.) > 7) Globals should not be defined in a .h file Well, duh. You'll get a linker error if you do. (At least if you include the header in more than one place.) > 8) Every .cpp file should compile into a .obj file without error or > warning on its own. Hmm, is there any other way? Or what do you mean "on its own"? I don't even know of any other way of compiling a C++ program than one compilation unit at a time.
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | comp.lang.c++
csiph-web