473,396 Members | 1,933 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Is there a class name macro?

Hi,

__PRETTY_FUNCTION__ is a macro that gives function name, etc. I'm
wondering if there is a macro to get the class name inside a member
function.

Thanks,
Peng
Sep 16 '08 #1
33 15089
Peng Yu wrote:
Hi,

__PRETTY_FUNCTION__ is a macro that gives function name, etc.
Is it?
I'm
wondering if there is a macro to get the class name inside a member
function.
Not in standard C++.

--
Ian Collins.
Sep 16 '08 #2
On Sep 15, 8:24 pm, Ian Collins <ian-n...@hotmail.comwrote:
Peng Yu wrote:
Hi,
__PRETTY_FUNCTION__ is a macro that gives function name, etc.

Is it?
I'm
wondering if there is a macro to get the class name inside a member
function.

Not in standard C++.
I know __PRETTY_FUNCTION__ is not in the standard. But the standard
has something similar to it, I just do remember what it is. But my
questions was on the class name.

Thanks,
Peng

Sep 16 '08 #3
Peng Yu wrote:
On Sep 15, 8:24 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Peng Yu wrote:
Hi,
__PRETTY_FUNCTION__ is a macro that gives function name, etc.

Is it?
I'm
wondering if there is a macro to get the class name inside a member
function.

Not in standard C++.

I know __PRETTY_FUNCTION__ is not in the standard. But the standard
has something similar to it, I just do remember what it is.
The standard has the following predefined macros [16.8]:

__LINE__
__FILE__
__DATE__
__TIME__
__STDC__
__cplusplus__

Everything else is implementation specific.

But my questions was on the class name.
And your question has been answered: "not in standard C++".
Best

Kai-Uwe Bux
Sep 16 '08 #4
use __func__, it is standard C, should be taken by any/most c++
compilers.

And your question has been answered: "not in standard C++".
Kai-Uwe Bux
:D

Sep 16 '08 #5
On Mon, 15 Sep 2008 19:53:15 -0700 (PDT), cu*****@spam.la wrote in
comp.lang.c++:
use __func__, it is standard C, should be taken by any/most c++
compilers.
It is standard C as of 1999, which is not yet a part of standard C++.

But in the part of the original post that you skipped:
__PRETTY_FUNCTION__ is a macro that gives function name, etc. I'm
wondering if there is a macro to get the class name inside a member
function.
....the __func__ macro, if/when it becomes part of C++, or is available
in a C++ compiler as an extension, still yields the function name, and
has nothing at all to do with the name of a class.
And your question has been answered: "not in standard C++".
Kai-Uwe Bux
So the above is still perfectly true.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Sep 16 '08 #6
On Sep 16, 4:07 am, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Peng Yu wrote:
On Sep 15, 8:24 pm, Ian Collins <ian-n...@hotmail.comwrote:
Peng Yu wrote:
__PRETTY_FUNCTION__ is a macro that gives function name, etc.
Is it?
I'm wondering if there is a macro to get the class name
inside a member function.
Not in standard C++.
I know __PRETTY_FUNCTION__ is not in the standard. But the standard
has something similar to it, I just do remember what it is.
The standard has the following predefined macros [16.8]:
__LINE__
__FILE__
__DATE__
__TIME__
__STDC__
__cplusplus__
Everything else is implementation specific.
Not entirely. A certain number of standard headers are also
guaranteed to define specific macros. In addition, C99 adds
some important macros which will doubtlessly end up in the next
standard, and in practice, should certainly be implemented by
every compiler today. (__STDC_IEC_559__ and __STDC_HOSTED__
come to mind.)

In C99, there is also a pre-defined identifier, __func__, which
contains the name of the function. C++0x will also have this,
but unlike C, given overloading, classes, namespaces and
templates, it's not clear what the string should contain.
(According to the current draft, it's implementation defined.)
But my questions was on the class name.
And your question has been answered: "not in standard C++".
And it won't be part of the next version of the standard,
either. (At least I don't think so.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 16 '08 #7
On Mon, 15 Sep 2008 22:10:35 -0500, Jack Klein <ja*******@spamcop.netwrote:
On Mon, 15 Sep 2008 19:53:15 -0700 (PDT), cu*****@spam.la wrote in
comp.lang.c++:
>use __func__, it is standard C, should be taken by any/most c++
compilers.

It is standard C as of 1999, which is not yet a part of standard C++.

But in the part of the original post that you skipped:
__PRETTY_FUNCTION__ is a macro that gives function name, etc. I'm
wondering if there is a macro to get the class name inside a member
function.

...the __func__ macro, if/when it becomes part of C++, or is available
in a C++ compiler as an extension, still yields the function name, and
has nothing at all to do with the name of a class.
"Nothing at all" is a bit strongly worded -- I'd expect it to work for
member functions, and the class name to be part of it. E.g. "Foo<int>"
in "Foo<int>::bar(const Baz&)".

I have used __func__ as a C++ extension in g++, but I forget exactly
how they chose to do it. It's in the documentation though.

/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.se R'lyeh wgah'nagl fhtagn!
Sep 16 '08 #8
On Sep 16, 2:31 pm, Jorgen Grahn <grahn+n...@snipabacken.sewrote:
On Mon, 15 Sep 2008 22:10:35 -0500, Jack Klein <jackkl...@spamcop.netwrote:
...the __func__ macro,
Just a nit, but it's not a macro, but a pre-defined variable.
if/when it becomes part of C++, or is available in a C++
compiler as an extension, still yields the function name,
and has nothing at all to do with the name of a class.
"Nothing at all" is a bit strongly worded -- I'd expect it to
work for member functions, and the class name to be part of
it. E.g. "Foo<int>" in "Foo<int>::bar(const Baz&)".
It's already present in the draft. The text is "implementation
defined", and could be simply "" in every case.
I have used __func__ as a C++ extension in g++, but I forget
exactly how they chose to do it. It's in the documentation
though.
They just output the simple function name.

The real question is what it is to be used for. What you want
to output depends on that, more than anything else. If it is
for logging messages, I'm not sure what is best. To find the
actual function, you need the fully qualified name, and even
that causes problems for anything in anonymous namespaces, or
member functions of local classes. And what about static
functions.

If the goal of putting it in a log file is to be able to find
the place in the source code later, a better solution is to use
__FILE__, __LINE__ and the version number inserted by your
version control system.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 16 '08 #9
James Kanze wrote:
On Sep 16, 2:31 pm, Jorgen Grahn <grahn+n...@snipabacken.sewrote:
>On Mon, 15 Sep 2008 22:10:35 -0500, Jack Klein <jackkl...@spamcop.net>
wrote:
...the __func__ macro,

Just a nit, but it's not a macro, but a pre-defined variable.
if/when it becomes part of C++, or is available in a C++
compiler as an extension, still yields the function name,
and has nothing at all to do with the name of a class.
>"Nothing at all" is a bit strongly worded -- I'd expect it to
work for member functions, and the class name to be part of
it. E.g. "Foo<int>" in "Foo<int>::bar(const Baz&)".

It's already present in the draft. The text is "implementation
defined", and could be simply "" in every case.
>I have used __func__ as a C++ extension in g++, but I forget
exactly how they chose to do it. It's in the documentation
though.

They just output the simple function name.

The real question is what it is to be used for.
I'll probably use it in my trace utility. In most cases I put classes in
files with the name of the class, so using
__FILE__ __func__ and __LINE__ will put an entry in my trace file that
indicates (in the majority of cases) the class and the function. For the
cases where the class does not have the same name as the file, or cases
where a function is overloaded, the __LINE__ will resolve the ambiguity.

My code will be simpler, because instead of putting:-

TRACE(ClassName::FunctionName);

at the start of each function, I'll just put:-

TRACE;

Thanks to the OP for drawing attention to this.

Chris Gordon-Smith
www.simsoup.info

Sep 16 '08 #10
Peng Yu schrieb:
On Sep 15, 8:24 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Peng Yu wrote:
>>Hi,
__PRETTY_FUNCTION__ is a macro that gives function name, etc.
Is it?
>>I'm
wondering if there is a macro to get the class name inside a member
function.
Not in standard C++.

I know __PRETTY_FUNCTION__ is not in the standard. But the standard
has something similar to it, I just do remember what it is. But my
questions was on the class name.
You can get the class name in a member using this:

typeid(*this).name()

However, the exact output depends on the implementation.

--
Thomas
Sep 16 '08 #11
On 2008-09-16 03:22, Peng Yu wrote:
Hi,

__PRETTY_FUNCTION__ is a macro that gives function name, etc. I'm
wondering if there is a macro to get the class name inside a member
function.
Most compilers have some way of getting the qualified name of a
function, usually in the form "ReturnType Class::Function(Param1,
Param2, ...)", however different compilers have different ways of doing
it. My advice is to define a macro which expands to the correct way
based on the compiler used.

--
Erik Wikström
Sep 16 '08 #12
On Sep 16, 9:18 pm, Chris Gordon-Smith <use.addr...@my.homepage>
wrote:
James Kanze wrote:
On Sep 16, 2:31 pm, Jorgen Grahn <grahn+n...@snipabacken.sewrote:
On Mon, 15 Sep 2008 22:10:35 -0500, Jack Klein <jackkl...@spamcop.net>
wrote:
...the __func__ macro,
Just a nit, but it's not a macro, but a pre-defined variable.
if/when it becomes part of C++, or is available in a C++
compiler as an extension, still yields the function name,
and has nothing at all to do with the name of a class.
"Nothing at all" is a bit strongly worded -- I'd expect it to
work for member functions, and the class name to be part of
it. E.g. "Foo<int>" in "Foo<int>::bar(const Baz&)".
It's already present in the draft. The text is "implementation
defined", and could be simply "" in every case.
I have used __func__ as a C++ extension in g++, but I forget
exactly how they chose to do it. It's in the documentation
though.
They just output the simple function name.
The real question is what it is to be used for.
I'll probably use it in my trace utility. In most cases I put
classes in files with the name of the class, so using __FILE__
__func__ and __LINE__ will put an entry in my trace file that
indicates (in the majority of cases) the class and the
function.
If you have the line number, and can find the source file, then
the filename and line number should indicate unambiguously which
class and which function the trace was in.

Finding the correct source file can be a bit tricky. That's why
I suggested adding some versioning information somewhere. (The
other alternative is to put the versioning information in static
C style strings in the file, and use something like "strings" to
read it from the executable, when needed.)
For the cases where the class does not have the same name as
the file, or cases where a function is overloaded, the
__LINE__ will resolve the ambiguity.
My code will be simpler, because instead of putting:-
TRACE(ClassName::FunctionName);
at the start of each function, I'll just put:-
TRACE;
Exactly. Generally, I think that there's such a thing as being
too succinct. But in the case of tracing, the easier it is to
use, the more it will be used. And that's what you want.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 16 '08 #13
On Sep 16, 9:45 pm, "Thomas J. Gritzan" <phygon_antis...@gmx.de>
wrote:
Peng Yu schrieb:
On Sep 15, 8:24 pm, Ian Collins <ian-n...@hotmail.comwrote:
Peng Yu wrote:
>__PRETTY_FUNCTION__ is a macro that gives function name, etc.
Is it?
>I'm
wondering if there is a macro to get the class name inside a member
function.
Not in standard C++.
I know __PRETTY_FUNCTION__ is not in the standard. But the standard
has something similar to it, I just do remember what it is. But my
questions was on the class name.
You can get the class name in a member using this:
typeid(*this).name()
However, the exact output depends on the implementation.
And is, in at least one wide spread implementation, almost
unusable.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 16 '08 #14
On Sep 16, 10:22 am, Peng Yu <PengYu...@gmail.comwrote:
Hi,

__PRETTY_FUNCTION__ is a macro that gives function name, etc. I'm
wondering if there is a macro to get the class name inside a member
function.

Thanks,
Peng
Your question almost answers itself. Just do a little parsing on the
__PRETTY_FUNCTION__ string to extract the class name. From quick
thought, I can't see any issue with scanning for '(' then working
backwards to "::" then taking the preceding identifier. You've got it
easy, as the types are already resolved for you - raw source code can
have templated types being instantiated with arbitrary expressions
also containing "(" etc..

Cheers,
Tony
Sep 17 '08 #15
On Sep 17, 10:06 am, tony_in_da...@yahoo.co.uk wrote:
On Sep 16, 10:22 am, Peng Yu <PengYu...@gmail.comwrote:
__PRETTY_FUNCTION__ is a macro that gives function name, etc. I'm
wondering if there is a macro to get the class name inside a member
function.

Your question almost answers itself. Just do a little parsing on the
__PRETTY_FUNCTION__ string to extract the class name. From quick
thought, I can't see any issue with scanning for '(' then working
backwards to "::" then taking the preceding identifier. You've got it
easy, as the types are already resolved for you - raw source code can
have templated types being instantiated with arbitrary expressions
also containing "(" etc..
std::string less_pretty(const char pretty_func[])
{
const char* p = strrchr(pretty_func, '(');
BOOTSTRAP_ASSERT(p);
const char* end = p;
while (p[-1] != ':' && p[-1] != ' ')
--p;
BOOTSTRAP_ASSERT(p pretty_func); // should always be space after
type...
const char* fn_name = p;
if (p[-1] == ':')
{
p -= 2;
BOOTSTRAP_ASSERT(p pretty_func && *p == ':');
while (p pretty_func && (isalnum(p[-1]) || p[-1] == '_'))
--p;
// simplify constructors "idn::idn()" back to idn()...
if (strncmp(p, fn_name, fn_name - p - sizeof(" ")) == 0)
p = fn_name;
}
// std::cerr << "less_pretty('" << pretty_func << "') return '"
// << std::string(p, end - p) << "'\n";
return std::string(p, end - p);
}
Sep 17 '08 #16
On Tue, 16 Sep 2008 07:28:42 -0700 (PDT), James Kanze <ja*********@gmail.comwrote:
On Sep 16, 2:31 pm, Jorgen Grahn <grahn+n...@snipabacken.sewrote:
....
>I have used __func__ as a C++ extension in g++, but I forget
exactly how they chose to do it. It's in the documentation
though.

They just output the simple function name.
Yes, you're right. Strange when you think of it -- you can have lots
of operator< (), set() and so on in even a medium-sized program.
The real question is what it is to be used for. What you want
to output depends on that, more than anything else. If it is
for logging messages, I'm not sure what is best. To find the
actual function, you need the fully qualified name, and even
that causes problems for anything in anonymous namespaces, or
member functions of local classes. And what about static
functions.
Surely the purpose is log/trace messages, assertions and so on. I can
see no other reason to have it, especially since it's
implementation-defined.
If the goal of putting it in a log file is to be able to find
the place in the source code later, a better solution is to use
__FILE__, __LINE__ and the version number inserted by your
version control system.
And version number isn't needed if you have some out-of-band way of
knowing what version produced the message, and finding the source code
for that version.

I have to say that for me, __func__ *is* useful.

I have used "date time: file:line function(): ..." a lot for log/trace
messages in one application. File and line is enough to find the
source code, but the function name gives context to the message you
are printing, so that the message itself can be more brief.

I have also been hacking code which used function names in trace
messages, but didn't use __func__. It's painful -- it gets in the way
when reading the code because function names appear in the strings
(false positives when you search or grep). Also, you can bet money
that some of the strings are incorrect due to cut & paste errors.

/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.se R'lyeh wgah'nagl fhtagn!
Sep 17 '08 #17
James Kanze wrote:

The real question is what it is to be used for.
>I'll probably use it in my trace utility. In most cases I put
classes in files with the name of the class, so using __FILE__
__func__ and __LINE__ will put an entry in my trace file that
indicates (in the majority of cases) the class and the
function.

If you have the line number, and can find the source file, then
the filename and line number should indicate unambiguously which
class and which function the trace was in.

Finding the correct source file can be a bit tricky. That's why
I suggested adding some versioning information somewhere. (The
other alternative is to put the versioning information in static
C style strings in the file, and use something like "strings" to
read it from the executable, when needed.)
I don't get your point. Can you explain?
I always trace the latest version of my program and the trace output will
include the filename, so why is finding the source file a bit tricky?

And why is versioning information needed, and what would that information
be?
>For the cases where the class does not have the same name as
the file, or cases where a function is overloaded, the
__LINE__ will resolve the ambiguity.
>My code will be simpler, because instead of putting:-
>TRACE(ClassName::FunctionName);
>at the start of each function, I'll just put:-
>TRACE;

Exactly. Generally, I think that there's such a thing as being
too succinct. But in the case of tracing, the easier it is to
use, the more it will be used. And that's what you want.
Yes, code must be easy to understand. My take on it would be that succinct
code is OK so long as it does not become cryptic and impenetrable.

Chris Gordn-Smith
www.simsoup.info
Sep 17 '08 #18
On Sep 17, 11:29 pm, Chris Gordon-Smith <use.addr...@my.homepage>
wrote:
James Kanze wrote:
The real question is what it is to be used for.
I'll probably use it in my trace utility. In most cases I put
classes in files with the name of the class, so using __FILE__
__func__ and __LINE__ will put an entry in my trace file that
indicates (in the majority of cases) the class and the
function.
If you have the line number, and can find the source file, then
the filename and line number should indicate unambiguously which
class and which function the trace was in.
Finding the correct source file can be a bit tricky. That's why
I suggested adding some versioning information somewhere. (The
other alternative is to put the versioning information in static
C style strings in the file, and use something like "strings" to
read it from the executable, when needed.)
I don't get your point. Can you explain?
As soon as you have two or more instances of the program,
fatally, sooner or later, you'll run into the problem of
different versions. And to exploit filename/line number, you
need to know the version of the file which created the trace.
I've almost always seen this in the form of static variables in
the code, and I've almost always had issues finding out which
executable generated the trace, and getting a copy of it, so
that I could know which version of the program generated the
trace. When all is said and done, it's probably a good idea to
add this information to the trace automatically. (And having
the trace macro refer to it ensures that it will be there; all
too often, I've found it missing completely, and you just have
to guess.)
I always trace the latest version of my program and the trace
output will include the filename, so why is finding the source
file a bit tricky?
If there is only one instance of the program in existance at any
one time, there's no problem. In practice, however, this isn't
the case that often.
And why is versioning information needed, and what would that
information be?
For the cases where the class does not have the same name
as the file, or cases where a function is overloaded, the
__LINE__ will resolve the ambiguity.
My code will be simpler, because instead of putting:-
TRACE(ClassName::FunctionName);
at the start of each function, I'll just put:-
TRACE;
Exactly. Generally, I think that there's such a thing as
being too succinct. But in the case of tracing, the easier
it is to use, the more it will be used. And that's what you
want.
Yes, code must be easy to understand. My take on it would be
that succinct code is OK so long as it does not become cryptic
and impenetrable.
Succinctness is, in itself, a quality. Good code should be
clear and concise. Generally speaking, however, using macros to
make code more succinct, and especially using a macro to hide a
function call, costs too much clarity to be considered. Tracing
is, IMHO, a special case, however: it's not part of the program
logic, and you really have to make it as easy to use as
possible, so that it will be used. (And of course, you want to
invoke it via a macro anyway, so that you can automatically
insert __FILE__ and __LINE__.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 18 '08 #19
James Kanze wrote:
On Sep 17, 11:29 pm, Chris Gordon-Smith <use.addr...@my.homepage>
wrote:
>James Kanze wrote:
The real question is what it is to be used for.
>I'll probably use it in my trace utility. In most cases I put
classes in files with the name of the class, so using __FILE__
__func__ and __LINE__ will put an entry in my trace file that
indicates (in the majority of cases) the class and the
function.
If you have the line number, and can find the source file, then
the filename and line number should indicate unambiguously which
class and which function the trace was in.
Finding the correct source file can be a bit tricky. That's why
I suggested adding some versioning information somewhere. (The
other alternative is to put the versioning information in static
C style strings in the file, and use something like "strings" to
read it from the executable, when needed.)
>I don't get your point. Can you explain?

As soon as you have two or more instances of the program,
fatally, sooner or later, you'll run into the problem of
different versions. And to exploit filename/line number, you
need to know the version of the file which created the trace.
I've almost always seen this in the form of static variables in
the code, and I've almost always had issues finding out which
executable generated the trace, and getting a copy of it, so
that I could know which version of the program generated the
trace. When all is said and done, it's probably a good idea to
add this information to the trace automatically. (And having
the trace macro refer to it ensures that it will be there; all
too often, I've found it missing completely, and you just have
to guess.)
OK - I see the point.

In my case things are a lot simpler. I'm doing a one person spare time
project so I don't have multiple program instances / parallel realease, and
I always know which execuatble generated trace output.
>I always trace the latest version of my program and the trace
output will include the filename, so why is finding the source
file a bit tricky?

If there is only one instance of the program in existance at any
one time, there's no problem. In practice, however, this isn't
the case that often.
>And why is versioning information needed, and what would that
information be?
>For the cases where the class does not have the same name
as the file, or cases where a function is overloaded, the
__LINE__ will resolve the ambiguity.
>My code will be simpler, because instead of putting:-
>TRACE(ClassName::FunctionName);
>at the start of each function, I'll just put:-
>TRACE;
Exactly. Generally, I think that there's such a thing as
being too succinct. But in the case of tracing, the easier
it is to use, the more it will be used. And that's what you
want.
>Yes, code must be easy to understand. My take on it would be
that succinct code is OK so long as it does not become cryptic
and impenetrable.

Succinctness is, in itself, a quality. Good code should be
clear and concise.
Indeed.
Generally speaking, however, using macros to
make code more succinct, and especially using a macro to hide a
function call, costs too much clarity to be considered. Tracing
is, IMHO, a special case, however: it's not part of the program
logic, and you really have to make it as easy to use as
possible, so that it will be used. (And of course, you want to
invoke it via a macro anyway, so that you can automatically
insert __FILE__ and __LINE__.)
I agree that in this case using a macro is OK (I suppose I must since I've
done it!). Macros do need to be used sparingly, and its important to keep
them as simple as possible. My TRACE macro has a single line, and by
calling the macro just once at the start of a function I get an 'Enter
Function' trace line and a second 'Leave Function' line just before the
function returns.

Another advantage of using a macro is that I can (and do) conditionally
compile it, so that I can completely remove the Trace code (although I can
also control it programmatically). Conditional compilation should also be
used sparingly, and this is the only place I use it in what has now become
a substantial sized project.

Another place I use macros is to replace curly brackets. Eg

// Global include

#define THEN {
#define ELSEIF }else if
#define ELSE }else{
#define ENDIF }
// -----------------

Then I can write

if (condition)
THEN
// Do something
ELSE
// Do something else
ENDIF

This may be controversial, but I think it makes code clearer. My code
automatically documents where the various parts of the if statement are,
rather than leaving the reader to count brackets and look at indentation.

Chris Gordon-Smith
www.simsoup.info

Sep 18 '08 #20
On Thu, 18 Sep 2008 21:13:35 +0100, Chris Gordon-Smith <us*********@my.homepagewrote:
James Kanze wrote:
>On Sep 17, 11:29 pm, Chris Gordon-Smith <use.addr...@my.homepage>
wrote:
>>James Kanze wrote:
....
>Finding the correct source file can be a bit tricky. That's why
I suggested adding some versioning information somewhere. (The
other alternative is to put the versioning information in static
C style strings in the file, and use something like "strings" to
read it from the executable, when needed.)
>>I don't get your point. Can you explain?

As soon as you have two or more instances of the program,
fatally, sooner or later, you'll run into the problem of
different versions. And to exploit filename/line number, you
need to know the version of the file which created the trace.
I've almost always seen this in the form of static variables in
the code, and I've almost always had issues finding out which
executable generated the trace, and getting a copy of it, so
that I could know which version of the program generated the
trace. When all is said and done, it's probably a good idea to
add this information to the trace automatically. (And having
the trace macro refer to it ensures that it will be there; all
too often, I've found it missing completely, and you just have
to guess.)
OK - I see the point.

In my case things are a lot simpler. I'm doing a one person spare time
project so I don't have multiple program instances / parallel realease, and
I always know which execuatble generated trace output.
>>I always trace the latest version of my program and the trace
output will include the filename, so why is finding the source
file a bit tricky?

If there is only one instance of the program in existance at any
one time, there's no problem. In practice, however, this isn't
the case that often.
It depends a lot on who your customers are. Where I am right now, they
are fairly close, and I can make demands. I make a point of only
giving them releases which can be traced back to one version of the
source code, and they know (or can find out) which release they are
using. Come to think of it, it's printed first in the log file.

In that scenario, file and line is enough.

/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.se R'lyeh wgah'nagl fhtagn!
Sep 19 '08 #21
On Sep 18, 10:13 pm, Chris Gordon-Smith <use.addr...@my.homepage>
wrote:
James Kanze wrote:
[...]
Another advantage of using a macro is that I can (and do)
conditionally compile it, so that I can completely remove the
Trace code (although I can also control it programmatically).
Conditional compilation should also be used sparingly, and
this is the only place I use it in what has now become a
substantial sized project.
I've provided for this possibility many times as well. I've
never had to use it, but often, it's a necessary argument to
sell tracing.
Another place I use macros is to replace curly brackets. Eg
// Global include
#define THEN {
#define ELSEIF }else if
#define ELSE }else{
#define ENDIF }
// -----------------
Then I can write
if (condition)
THEN
// Do something
ELSE
// Do something else
ENDIF
This may be controversial,
It's not controversial; it's proven bad practice. You've just
made your code unreadable by any other C++ programmer, and by
any other tool which doesn't to a full parse (syntax
highlighting and indenting by the editor, for example).

C++ has a defined syntax. I don't always like it either, but
that's the way it is. You can't really create a new language
with macros, and you don't really want to, since no one else
(and no tool) knows that language. For better or for worse, you
have to live with C++ as it is.

(Also, if you were doing it, the #defines would be:

#define IF if (
#define THEN ) {
#define ELSE } else {
#define ELSIF } else if (
#define END }

..)
but I think it makes code clearer. My code automatically
documents where the various parts of the if statement are,
rather than leaving the reader to count brackets and look at
indentation.
How is counting the brackets and looking at the indentation any
better than counting the THEN/ELSE and looking at the
indentation. My editor does the indentation automatically (as
do most, I think), which ensures that it is correct, and it's
doubtlessly the easiest thing to follow. (And of course, I
don't nest overly deep, so there's not that much to follow
anyway.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 19 '08 #22
On Sep 19, 9:12 am, Jorgen Grahn <grahn+n...@snipabacken.sewrote:
On Thu, 18 Sep 2008 21:13:35 +0100, Chris Gordon-Smith
<use.addr...@my.homepagewrote:
[...]
If there is only one instance of the program in existance
at any one time, there's no problem. In practice, however,
this isn't the case that often.
It depends a lot on who your customers are. Where I am right
now, they are fairly close, and I can make demands. I make a
point of only giving them releases which can be traced back to
one version of the source code, and they know (or can find
out) which release they are using. Come to think of it, it's
printed first in the log file.
In that scenario, file and line is enough.
If you're managing your sources correctly, that should be
enough. In practice, it depends on the organization, and more
than once, even knowing the version of the executable, I've had
difficulty determining which version of a specific source it
contained. In such cases, adding the version only adds a few
characters to the line header (which already contains the
filename, line number and a timestamp), and seems worth it. In
better run organizations, it's probably not worth the bother.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 19 '08 #23
James Kanze wrote:
On Sep 18, 10:13 pm, Chris Gordon-Smith <use.addr...@my.homepage>
wrote:
>James Kanze wrote:

[...]
>Another advantage of using a macro is that I can (and do)
conditionally compile it, so that I can completely remove the
Trace code (although I can also control it programmatically).
Conditional compilation should also be used sparingly, and
this is the only place I use it in what has now become a
substantial sized project.

I've provided for this possibility many times as well. I've
never had to use it, but often, it's a necessary argument to
sell tracing.
>Another place I use macros is to replace curly brackets. Eg
>// Global include
>#define THEN {
#define ELSEIF }else if
#define ELSE }else{
#define ENDIF }
// -----------------
>Then I can write
>if (condition)
THEN
// Do something
ELSE
// Do something else
ENDIF
>This may be controversial,

It's not controversial; it's proven bad practice. You've just
made your code unreadable by any other C++ programmer, and by
any other tool which doesn't to a full parse (syntax
highlighting and indenting by the editor, for example).
I think the main issue when picking up someone else's code is understanding
the overall application design, how it works, and all the other application
specific aspects. Finding your way around unfamiliar (but intuitive) syntax
is a small step compared to this.

Syntax highlighting works with my editor.
>
C++ has a defined syntax. I don't always like it either, but
that's the way it is. You can't really create a new language
with macros, and you don't really want to, since no one else
(and no tool) knows that language. For better or for worse, you
have to live with C++ as it is.
I haven't created a new language, but I have varied the syntax slightly. It
is working fine for me, and I don't have to live with the curly brackets
that annoy me. I do realise however that the approach I like may annoy
other people.
>
(Also, if you were doing it, the #defines would be:

#define IF if (
#define THEN ) {
#define ELSE } else {
#define ELSIF } else if (
#define END }

.)
The seem to be different ways of doing it. I don't have a #define for "if"
(that does seem to be unnecessary), and I have separate #defines for END
and ENDIF. That way I can distinguish between the end of an "if" statement
and the end of a "for" loop (for which I use END).
>
>but I think it makes code clearer. My code automatically
documents where the various parts of the if statement are,
rather than leaving the reader to count brackets and look at
indentation.

How is counting the brackets and looking at the indentation any
better than counting the THEN/ELSE and looking at the
indentation.
There is less reliance on counting and checking indentation. Instead of
looking at a "}"curly bracket and wondering what kind of block it ends, I
see ENDIF and know immediately what it means.
My editor does the indentation automatically (as
do most, I think), which ensures that it is correct, and it's
doubtlessly the easiest thing to follow. (And of course, I
don't nest overly deep, so there's not that much to follow
anyway.)
I don't use automatic indentation. I tried it for a while with Emacs but
couldn't get it to indent the way I wanted.

Agree about the over-deep nesting.

Chris Gordon-Smith
www.simsoup.info
Sep 19 '08 #24
In message <6j************@mid.individual.net>, Chris Gordon-Smith
<us*********@my.homepagewrites
>James Kanze wrote:
>On Sep 18, 10:13 pm, Chris Gordon-Smith <use.addr...@my.homepage>
wrote:
>>#define THEN {
[etc]
>>
>>This may be controversial,

It's not controversial; it's proven bad practice. You've just
made your code unreadable by any other C++ programmer, and by
any other tool which doesn't to a full parse (syntax
highlighting and indenting by the editor, for example).
I think the main issue when picking up someone else's code is understanding
the overall application design, how it works, and all the other application
specific aspects. Finding your way around unfamiliar (but intuitive)
Intuitive? ...
>syntax
is a small step compared to this.

Syntax highlighting works with my editor.
>>
C++ has a defined syntax. I don't always like it either, but
that's the way it is. You can't really create a new language
with macros, and you don't really want to, since no one else
(and no tool) knows that language. For better or for worse, you
have to live with C++ as it is.
I haven't created a new language, but I have varied the syntax slightly. It
is working fine for me, and I don't have to live with the curly brackets
that annoy me. I do realise however that the approach I like may annoy
other people.
Meiosis.
>>
(Also, if you were doing it, the #defines would be:

#define IF if (
#define THEN ) {
#define ELSE } else {
#define ELSIF } else if (
#define END }

.)

The seem to be different ways of doing it.
.... which implies that it's not intuitive, as claimed above.
I don't have a #define for "if"
(that does seem to be unnecessary),
(and the other macros aren't?)

So you have a construct with a language keyword at the top and macros
elsewhere. Foolish consistency, at the very least, would dictate using
macros throughout if you must use then at all.
>and I have separate #defines for END
and ENDIF. That way I can distinguish between the end of an "if" statement
and the end of a "for" loop (for which I use END).
(why not ENDFOR?)
But can someone else who picks up your code and doesn't notice that
there are two macros for } ?
>>
>>but I think it makes code clearer. My code automatically
documents where the various parts of the if statement are,
rather than leaving the reader to count brackets and look at
indentation.

How is counting the brackets and looking at the indentation any
better than counting the THEN/ELSE and looking at the
indentation.
There is less reliance on counting and checking indentation. Instead of
looking at a "}"curly bracket and wondering what kind of block it ends,
The usual solution to that is to write, mutatis mutandis, something like
} // end if (condition)
>I
see ENDIF and know immediately what it means.
Unless you (or someone else) typed the wrong macro :-(
The compiler won't provide any helpful error messages if you do.
>
>My editor does the indentation automatically (as
do most, I think), which ensures that it is correct, and it's
doubtlessly the easiest thing to follow. (And of course, I
don't nest overly deep, so there's not that much to follow
anyway.)

I don't use automatic indentation. I tried it for a while with Emacs but
couldn't get it to indent the way I wanted.

Agree about the over-deep nesting.
--
Richard Herring
Sep 22 '08 #25
On Sep 22, 10:54 am, Richard Herring <ju**@[127.0.0.1]wrote:
In message <6jifmvF3ht0...@mid.individual.net>, Chris Gordon-Smith
<use.addr...@my.homepagewrites
James Kanze wrote:
On Sep 18, 10:13 pm, Chris Gordon-Smith <use.addr...@my.homepage>
wrote:
#define THEN {
[etc]
(Also, if you were doing it, the #defines would be:
#define IF if (
#define THEN ) {
#define ELSE } else {
#define ELSIF } else if (
#define END }
.)
The seem to be different ways of doing it.
... which implies that it's not intuitive, as claimed above.
I don't have a #define for "if"
(that does seem to be unnecessary),
(and the other macros aren't?)
So you have a construct with a language keyword at the top and
macros elsewhere. Foolish consistency, at the very least,
would dictate using macros throughout if you must use then at
all.
Consistency would dictate that at the very least, if THEN and
ELSE are all caps, then IF should be as well. And probably all
of the other keywords, which means a few more macros.

IMHO, consistency would also dictate that if you aren't writing
C++, you conform to the use of some other language, which is why
my definitions of IF and THEN have the parentheses. Of course,
common sense would also dictate that if you want to write in
some other language, the obvious solution would be to use a
compiler for that language, and not to try to fool the C++
compiler (and your readers).
and I have separate #defines for END
and ENDIF. That way I can distinguish between the end of an "if" statement
and the end of a "for" loop (for which I use END).
(why not ENDFOR?)
And ENDWHILE. And ENDFUNCTION, and ENDCLASS. Let's do this
right:-).
But can someone else who picks up your code and doesn't notice
that there are two macros for } ?
And for {, I suppose. Otherwise:

for ( ... ) {
// ...
END
>but I think it makes code clearer. My code automatically
documents where the various parts of the if statement are,
rather than leaving the reader to count brackets and look at
indentation.
How is counting the brackets and looking at the indentation
any better than counting the THEN/ELSE and looking at the
indentation.
There is less reliance on counting and checking indentation.
Instead of looking at a "}"curly bracket and wondering what
kind of block it ends,
The usual solution to that is to write, mutatis mutandis,
something like
} // end if (condition)
The one point I'd disagree with. The usual solution is to
write:
}
, correctly indented, and if the { is so far away that it isn't
evident, then to break the function up into smaller, more
manageable chunks.
I see ENDIF and know immediately what it means.
Unless you (or someone else) typed the wrong macro :-( The
compiler won't provide any helpful error messages if you do.
And of course, the casual reader won't know exactly what it
means.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 22 '08 #26
In message
<01**********************************@e53g2000hsa. googlegroups.com>,
James Kanze <ja*********@gmail.comwrites
>On Sep 22, 10:54 am, Richard Herring <ju**@[127.0.0.1]wrote:
>In message <6jifmvF3ht0...@mid.individual.net>, Chris Gordon-Smith
<use.addr...@my.homepagewrites
>James Kanze wrote:
>On Sep 18, 10:13 pm, Chris Gordon-Smith <use.addr...@my.homepage>
wrote:
#define THEN {
>[etc]
>(Also, if you were doing it, the #defines would be:
> #define IF if (
#define THEN ) {
#define ELSE } else {
#define ELSIF } else if (
#define END }
>.)
>The seem to be different ways of doing it.
>... which implies that it's not intuitive, as claimed above.
I don't have a #define for "if"
(that does seem to be unnecessary),
>(and the other macros aren't?)
>So you have a construct with a language keyword at the top and
macros elsewhere. Foolish consistency, at the very least,
would dictate using macros throughout if you must use then at
all.

Consistency would dictate that at the very least, if THEN and
ELSE are all caps, then IF should be as well. And probably all
of the other keywords, which means a few more macros.

IMHO, consistency would also dictate that if you aren't writing
C++, you conform to the use of some other language, which is why
my definitions of IF and THEN have the parentheses. Of course,
common sense would also dictate that if you want to write in
some other language, the obvious solution would be to use a
compiler for that language, and not to try to fool the C++
compiler (and your readers).
>and I have separate #defines for END
and ENDIF. That way I can distinguish between the end of an "if" statement
and the end of a "for" loop (for which I use END).
>(why not ENDFOR?)

And ENDWHILE. And ENDFUNCTION, and ENDCLASS. Let's do this
right:-).
>But can someone else who picks up your code and doesn't notice
that there are two macros for } ?

And for {, I suppose. Otherwise:

for ( ... ) {
// ...
END
>>but I think it makes code clearer. My code automatically
documents where the various parts of the if statement are,
rather than leaving the reader to count brackets and look at
indentation.
>How is counting the brackets and looking at the indentation
any better than counting the THEN/ELSE and looking at the
indentation.
There is less reliance on counting and checking indentation.
Instead of looking at a "}"curly bracket and wondering what
kind of block it ends,
>The usual solution to that is to write, mutatis mutandis,
something like
>} // end if (condition)

The one point I'd disagree with. The usual solution is to
write:
}
, correctly indented, and if the { is so far away that it isn't
evident, then to break the function up into smaller, more
manageable chunks.
I suspect I write more multidimensional numerical code than you do.
Sometimes the "most manageable chunk" is unavoidably several levels deep
in nested loops, and splitting it into separate functions would actually
obscure the structure of the algorithm.

Besides, in the OP's case:
>>>I don't use automatic indentation. I tried it for a while with Emacs
but couldn't get it to indent the way I wanted.
;-/

--
Richard Herring
Sep 22 '08 #27
Richard Herring wrote:
In message
<01**********************************@e53g2000hsa. googlegroups.com>,
James Kanze <ja*********@gmail.comwrites
>[...]
The one point I'd disagree with. The usual solution is to
write:
}
, correctly indented, and if the { is so far away that it isn't
evident, then to break the function up into smaller, more
manageable chunks.

I suspect I write more multidimensional numerical code than you do.
Sometimes the "most manageable chunk" is unavoidably several levels deep
in nested loops, and splitting it into separate functions would actually
obscure the structure of the algorithm.
I have never seen an algorithm that wouldn't benefit from
giving parts of them names and calling it by those. Would
you care to give an example?

Schobi
Sep 22 '08 #28
Richard Herring wrote:
In message
<01**********************************@e53g2000hsa. googlegroups.com>,
James Kanze <ja*********@gmail.comwrites
>>On Sep 22, 10:54 am, Richard Herring <ju**@[127.0.0.1]wrote:
>>In message <6jifmvF3ht0...@mid.individual.net>, Chris Gordon-Smith
<use.addr...@my.homepagewrites
>>James Kanze wrote:
>>On Sep 18, 10:13 pm, Chris Gordon-Smith <use.addr...@my.homepage>
wrote:
#define THEN {
>>[etc]
(Also, if you were doing it, the #defines would be:
>> #define IF if (
#define THEN ) {
#define ELSE } else {
#define ELSIF } else if (
#define END }
>>.)

The seem to be different ways of doing it.
>>... which implies that it's not intuitive, as claimed above.
Its the syntax that is intuitive, not necessarily the macros used to enable
it.
>>
>I don't have a #define for "if"
(that does seem to be unnecessary),
>>(and the other macros aren't?)
>>So you have a construct with a language keyword at the top and
macros elsewhere. Foolish consistency, at the very least,
would dictate using macros throughout if you must use then at
all.
I use the macros to make the code more readable to me. I find that
replacing "}" with "ENDIF" helps understanding. Replacing "if" with "IF"
would not help understanding. It would have the disadvantage of removing
syntax highlighting with no compensating advantage.
>>
Consistency would dictate that at the very least, if THEN and
ELSE are all caps, then IF should be as well. And probably all
of the other keywords, which means a few more macros.

IMHO, consistency would also dictate that if you aren't writing
C++, you conform to the use of some other language, which is why
my definitions of IF and THEN have the parentheses.
The code compiles, so strictly speakig I think it must be C++, albeit with
somewhat unusual usage.
>>Of course,
common sense would also dictate that if you want to write in
some other language, the obvious solution would be to use a
compiler for that language, and not to try to fool the C++
compiler (and your readers).
>>and I have separate #defines for END
and ENDIF. That way I can distinguish between the end of an "if"
statement and the end of a "for" loop (for which I use END).
>>(why not ENDFOR?)

And ENDWHILE. And ENDFUNCTION, and ENDCLASS. Let's do this
right:-).
>>But can someone else who picks up your code and doesn't notice
that there are two macros for } ?
I think they would very soon work it out.
>>
And for {, I suppose. Otherwise:

for ( ... ) {
// ...
END
>>>but I think it makes code clearer. My code automatically
documents where the various parts of the if statement are,
rather than leaving the reader to count brackets and look at
indentation.
>>How is counting the brackets and looking at the indentation
any better than counting the THEN/ELSE and looking at the
indentation.
There is less reliance on counting and checking indentation.
Instead of looking at a "}"curly bracket and wondering what
kind of block it ends,
>>The usual solution to that is to write, mutatis mutandis,
something like
>>} // end if (condition)
Where possible, I prefer to write code that documents itself rather than
write a comment.
>>
The one point I'd disagree with. The usual solution is to
write:
}
, correctly indented, and if the { is so far away that it isn't
evident, then to break the function up into smaller, more
manageable chunks.

I suspect I write more multidimensional numerical code than you do.
Sometimes the "most manageable chunk" is unavoidably several levels deep
in nested loops, and splitting it into separate functions would actually
obscure the structure of the algorithm.

Besides, in the OP's case:
>>>>I don't use automatic indentation. I tried it for a while with Emacs
but couldn't get it to indent the way I wanted.

;-/
I'll make a couple of other points on this overall discussion.

1) Personal Project Taste

This is an approach I have chosen to adopt for a particular project. It is
used consistently throughout the project.

I see it as a matter of personal taste, not as an issue of fundamental
importance that anyone should take an entrenched position over.

This is in contrast with principles such as good use of modularisation,
information hiding, minimising dependencies, appropriate use of inheritance
and polymorphism. These are issues that "really matter", and over which it
is worth arguing to get the approach right.

I am reminded of the item "Don't Sweat The Small Stuff" in Sutter and
Alexandrescu's C++ Coding Standards.

2) Tolerance for Different Approaches

I started re-reading Stroustrup's "The Design and Evolution of C++" over the
weekend. Here is a quote from section 1.3 (General Background):-

"Often when I was tempted to outlaw a feature I personally disliked, I
refrained from doing so because I did not think I had the right to force my
views on others. ..... A high degree of tolerance and acceptance that
different people think in different ways and strongly prefer to do things
differently is to me far preferable"

I think this is a good general principle, particularly in a case such as
this which is a matter of taste rather than one of fundamental importance.

Chris Gordon-Smith
www.simsoup.info

Sep 22 '08 #29
In message <gb**********@cb.generation-online.de>, Hendrik Schober
<sp******@gmx.dewrites
>Richard Herring wrote:
>In message <01**********************************@e53g2000hsa. googleg
roups.com>, James Kanze <ja*********@gmail.comwrites
>>[...] The one point I'd disagree with. The usual solution is to
write:
}
, correctly indented, and if the { is so far away that it isn't
evident, then to break the function up into smaller, more
manageable chunks.
I suspect I write more multidimensional numerical code than you do.
Sometimes the "most manageable chunk" is unavoidably several levels
deep in nested loops, and splitting it into separate functions would
actually obscure the structure of the algorithm.

I have never seen an algorithm that wouldn't benefit from
giving parts of them names and calling it by those.
Only if a meaningful name for the part is shorter than the code it
contains ;-)
>Would
you care to give an example?
Just look at FFT or matrix inversion code, or something similar. Here's
a fragment taken from a simple one-dimensional FFT:

int j = 0;
for (int i = 0; i<n; ++i)
{
if (j>i)
{
for (int k=0; k<span; ++k)
{
swap(a[span*i+k], a[span*j+k]);
}
}
int m = n/2;
while (m>=2 && j>=m)
{
j -= m;
m /= 2;
}
j += m;
}

--
Richard Herring
Sep 23 '08 #30
Richard Herring wrote:
In message <gb**********@cb.generation-online.de>, Hendrik Schober
<sp******@gmx.dewrites
>Richard Herring wrote:
>>In message <01**********************************@e53g2000hsa. googleg
roups.com>, James Kanze <ja*********@gmail.comwrites
[...] The one point I'd disagree with. The usual solution is to
write:
}
, correctly indented, and if the { is so far away that it isn't
evident, then to break the function up into smaller, more
manageable chunks.
I suspect I write more multidimensional numerical code than you do.
Sometimes the "most manageable chunk" is unavoidably several levels
deep in nested loops, and splitting it into separate functions would
actually obscure the structure of the algorithm.
I have never seen an algorithm that wouldn't benefit from
giving parts of them names and calling it by those.

Only if a meaningful name for the part is shorter than the code it
contains ;-)
>Would
you care to give an example?

Just look at FFT or matrix inversion code, or something similar. Here's
a fragment taken from a simple one-dimensional FFT:

int j = 0;
for (int i = 0; i<n; ++i)
{
if (j>i)
{
for (int k=0; k<span; ++k)
{
swap(a[span*i+k], a[span*j+k]);
}
}
int m = n/2;
while (m>=2 && j>=m)
{
j -= m;
m /= 2;
}
j += m;
}
This doesn't apply. Neither do I see the need to mark all } with
the keyword that required it nor do I see a need to move parts
of this into its own functions. So I remain not convinced.
Do you have any better example?

Schobi
Sep 24 '08 #31
In message <gb**********@cb.generation-online.de>, Hendrik Schober
<sp******@gmx.dewrites
>Richard Herring wrote:
>In message <gb**********@cb.generation-online.de>, Hendrik Schober
<sp******@gmx.dewrites
>>Richard Herring wrote:
In message <01**********************************@e53g2000hsa. googleg
roups.com>, James Kanze <ja*********@gmail.comwrites
[...] The one point I'd disagree with. The usual solution is to
write:
}
, correctly indented, and if the { is so far away that it isn't
evident, then to break the function up into smaller, more
manageable chunks.
I suspect I write more multidimensional numerical code than you do.
Sometimes the "most manageable chunk" is unavoidably several levels
deep in nested loops, and splitting it into separate functions would
actually obscure the structure of the algorithm.
I have never seen an algorithm that wouldn't benefit from
giving parts of them names and calling it by those.
Only if a meaningful name for the part is shorter than the code it
contains ;-)
>>Would
you care to give an example?
Just look at FFT or matrix inversion code, or something similar.
Here's
a fragment taken from a simple one-dimensional FFT:
int j = 0;
for (int i = 0; i<n; ++i)
{
if (j>i)
{
for (int k=0; k<span; ++k)
{
swap(a[span*i+k], a[span*j+k]);
}
}
int m = n/2;
while (m>=2 && j>=m)
{
j -= m;
m /= 2;
}
j += m;
}

This doesn't apply.
?
>Neither do I see the need to mark all } with
the keyword that required it nor do I see a need to move parts
of this into its own functions.
But it has three levels of nesting, which some people seem to think is
too many. Yet you agree that it:
>>>wouldn't benefit from
giving parts of them names and calling it by those.
and I submit that you would find it difficult to give any of those inner
blocks a meaningful name.
>So I remain not convinced.
Do you have any better example?
No, that's just a fragment of code that was to hand. I'm not inclined to
go digging for the perfect example, in the hope that I might eventually
find something that will "apply".

--
Richard Herring
Sep 24 '08 #32
Richard Herring wrote:
In message <gb**********@cb.generation-online.de>, Hendrik Schober
<sp******@gmx.dewrites
>Richard Herring wrote:
>>In message <gb**********@cb.generation-online.de>, Hendrik Schober
<sp******@gmx.dewrites
Richard Herring wrote:
In message <01**********************************@e53g2000hsa. googleg
roups.com>, James Kanze <ja*********@gmail.comwrites
>[...] The one point I'd disagree with. The usual solution is to
>write:
> }
>, correctly indented, and if the { is so far away that it isn't
>evident, then to break the function up into smaller, more
>manageable chunks.
I suspect I write more multidimensional numerical code than you do.
Sometimes the "most manageable chunk" is unavoidably several levels
deep in nested loops, and splitting it into separate functions would
actually obscure the structure of the algorithm.
I have never seen an algorithm that wouldn't benefit from
giving parts of them names and calling it by those.
Only if a meaningful name for the part is shorter than the code it
contains ;-)

Would
you care to give an example?
Just look at FFT or matrix inversion code, or something similar.
Here's
a fragment taken from a simple one-dimensional FFT:
int j = 0;
for (int i = 0; i<n; ++i)
{
if (j>i)
{
for (int k=0; k<span; ++k)
{
swap(a[span*i+k], a[span*j+k]);
}
}
int m = n/2;
while (m>=2 && j>=m)
{
j -= m;
m /= 2;
}
j += m;
}
This doesn't apply.

?
see below:
>Neither do I see the need to mark all } with
the keyword that required it nor do I see a need to move parts
of this into its own functions.

But it has three levels of nesting, which some people seem to think is
too many. Yet you agree that it:
>>>wouldn't benefit from
giving parts of them names and calling it by those.
It hasn't even 20 lines, and thus would even fit on an
ancient monochrome amber monitor. If it is an algorithm
that's well-known in the problem domain (I wouldn't know)
and if this is a whole function which is properly named,
I see no problem with this. And I see this as one of these
cases I thought James would refer to when he said proper
brace alignment would suffice.
[...]
Schobi
Sep 24 '08 #33
On Mon, 22 Sep 2008 21:42:17 +0100, Chris Gordon-Smith <us*********@my.homepagewrote:

[#define ELSE ... etc]
I'll make a couple of other points on this overall discussion.
....
2) Tolerance for Different Approaches

I started re-reading Stroustrup's "The Design and Evolution of C++" over the
weekend. Here is a quote from section 1.3 (General Background):-

"Often when I was tempted to outlaw a feature I personally disliked, I
refrained from doing so because I did not think I had the right to force my
views on others. ..... A high degree of tolerance and acceptance that
different people think in different ways and strongly prefer to do things
differently is to me far preferable"

I think this is a good general principle, particularly in a case such as
this which is a matter of taste rather than one of fundamental importance.
It's (in my opinion) the correct approach for someone designing a
language like C++. I interpret it as "Do not try to guess what's good
practice or not; the users will do a better job at finding that out."

But it does not mean that everyone else should approve of every C++
macro trick people can come up with. It just means Bjarne won't show
up at your door and take your C++ compiler away.

regards,
/Jorgen

--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.se R'lyeh wgah'nagl fhtagn!
Sep 24 '08 #34

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: stephan beal | last post by:
Good afternoon, C++ers, This weekend i came across a fairly project-neutral trick which can be used to map C++ class names to their human-readable equivalents (a-la QObject's className()...
4
by: pixelbeast | last post by:
hi, In the following code, I would like not to have to declare the constructors in bar ( either the default or the (int a) constructor ). When I remove them, bar has no idea of construction with...
4
by: Ced | last post by:
Hi, i'm not an expert in C but i try to compile BTNG software under linux kernel 2.4.2-2. I get these errors at the very first stage. Does someone could have a rapid look on this and tell me...
12
by: Sunny | last post by:
Hi All, I have a serious issue regarding classes scope and visibility. In my application, i have a class name "TextFile", and also a few other classes like "TotalWords", "TotalLines" and etc..,...
17
by: sounak | last post by:
How could we get a macro name from a macro value such that in a header file #define a 100 #define b 200 now the source file will be such that the user gives 100 then the value is outputted as...
48
by: mahurshi | last post by:
I am new to c++ classes. I defined this "cDie" class that would return a value between 1 and 6 (inclusive) It runs fine and gives no warnings during compilation. I was wondering if you guys...
9
by: silversurfer2025 | last post by:
Hello everyone, I am currently having problems with a C++ abstract class. I have a class FrameWork.h which defines some methods (of which some are abstract, i.e. virtual void method() = 0). In...
8
by: nandakumar.raghu | last post by:
Hi, I am creating a #defined class like - #define BEGIN_TEST_MAP(testmapname) class testmapname\ {\ testmapname(){}\ testmapname(std::ofstream resultfile)\ {\ resultfile << "<Test name=\""...
0
by: forgedascendant | last post by:
Good day everyone, I am new to this site so please forgive me if this post isn't completly correct. For the past 2 weeks I have been beating my head against the wall trying to figure out what is...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.