Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Fizz Buzz

112 views
Skip to first unread message

Rick C. Hodgin

unread,
Jul 17, 2018, 3:26:35 PM7/17/18
to
Somebody posted on comp.lang.asm.x86 an algorithm for fizz buzz.
It made me think of one here in C/C++.

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

void fizz(int num) { printf("fizz\n"); }
void buzz(int num) { printf("buzz\n"); }
void fizzbuzz(int num) { printf("fizzbuzz\n"); }
void other(int num) { printf("%d\n", num); }

struct STargets { void (*func)(int num); };
struct STargets funcs[4] = { other, fizz, buzz, fizzbuzz };

// Cycling bit patterns
uint32_t three_data = 0x924;
uint32_t five_data = 0x84210;

int main(int argc, char* argv[])
{
for (int lnI = 1; lnI <= 100; ++lnI)
{
funcs[(three_data & 1) + (2 * (five_data & 1))].func(lnI);

three_data = (three_data >> 1) | ((three_data & 1) << 11);
five_data = (five_data >> 1) | ((five_data & 1) << 19);
}
return(0);
}

The rules of the FizzBuzz game are here:

http://wiki.c2.com/?FizzBuzzTest

--
Rick C. Hodgin

Rick C. Hodgin

unread,
Jul 18, 2018, 8:22:58 AM7/18/18
to
On 7/17/2018 3:26 PM, Rick C. Hodgin wrote:
> Somebody posted on comp.lang.asm.x86 an algorithm for fizz buzz.
> It made me think of one here in C/C++.

An optimization occurred to me driving in to work this morning.

>     #include <stdlib.h>
>     #include <stdio.h>
>     #include <stdint.h>
>
>     void fizz(int num)        { printf("fizz\n");           }
>     void buzz(int num)        { printf("buzz\n");           }
>     void fizzbuzz(int num)    { printf("fizzbuzz\n");       }
>     void other(int num)       { printf("%d\n", num);        }
>
>     struct STargets            { void (*func)(int num);      };
>     struct STargets funcs[4] = { other, fizz, buzz, fizzbuzz };
>
>     // Cycling bit patterns
>     uint32_t three_data = 0x924;
>     uint32_t five_data  = 0x84210;

Shift the five_data bit pattern left by one bit:

uint32_t five_data = 0x84210 << 1;

>
>     int main(int argc, char* argv[])
>     {
>         for (int lnI = 1; lnI <= 100; ++lnI)
>         {
>             funcs[(three_data & 1) + (2 * (five_data & 1))].func(lnI);

It removes the need for a multiply here:

funcs[(three_data & 1) + (five_data & 2)].func(lnI);

>             three_data = (three_data >> 1) | ((three_data & 1) << 11);
>             five_data  = (five_data  >> 1) | ((five_data  & 1) << 19);

Then shift over 20 instead of 19:

five_data = (five_data >> 1) | ((five_data & 1) << 20);

>         }
>         return(0);
>     }
>
> The rules of the FizzBuzz game are here:
>
>     http://wiki.c2.com/?FizzBuzzTest


Just popped in my head while driving. If there are any others, please
post them. I like this solution. Seems simple and elegant.

--
Rick C. Hodgin

Ben Bacarisse

unread,
Jul 18, 2018, 10:39:14 AM7/18/18
to
It's always good to see a wide range of opinions. I find your
assessment very odd as the program contains redundant code, unnecessary
globals, overly mysterious constants, odd variable names, unused
variables, an unnecessary include and overly specific types. These are
details though, and I'll explain the biggest issue I have with it later
on.

Removing the unnecessary struct, making local data local, simplifying
the types and writing the bit patterns in their simplest and (to me)
most obvious form, we get:

#include <stdio.h>

void fizz(int num) { printf("fizz\n"); }
void buzz(int num) { printf("buzz\n"); }
void fizzbuzz(int num) { printf("fizzbuzz\n"); }
void other(int num) { printf("%d\n", num); }

int main(void)
{
void (*funcs[4])(int) = { other, fizz, buzz, fizzbuzz };
int threes = 1 << 2, fives = 1 << 4;

for (int i = 1; i <= 100; i++) {
funcs[(threes & 1) + (2 * (fives & 1))](i);
threes = (threes >> 1) | ((threes & 1) << 2);
fives = (fives >> 1) | ((fives & 1) << 4);
}
}

though even this tidied-up version has a magic expression in the array
index.

But the biggest problem is that the output depends on some state that
must be updated in line with the loop variable -- if the loop were
changed to test only every other int, the code would break. The 'i++'
and the two bit rotations are tied together.

I'd favour a solution where there is a single, separable bit of code
that prints the required output based solely on the number being
considered. For example

#include <stdio.h>

int main(void)
{
const char *const f = "fizz", *const b = "buzz";
for (int i = 1; i <= 100; i++) {
switch (i % 15) {
case 0:
fputs(f, stdout);
fputs(b, stdout);
break;
case 3: case 6: case 9: case 12:
fputs(f, stdout);
break;
case 5: case 10:
fputs(b, stdout);
break;
default:
printf("%d", i);
}
putchar('\n');
}
}

--
Ben.

Rick C. Hodgin

unread,
Jul 18, 2018, 10:51:37 AM7/18/18
to
On 7/18/2018 10:38 AM, Ben Bacarisse wrote:
> "Rick C. Hodgin" <rick.c...@gmail.com> writes:
>> Just popped in my head while driving. If there are any others, please
>> post them. I like this solution. Seems simple and elegant.
>
> It's always good to see a wide range of opinions. I find your
> assessment very odd as the program contains redundant code, unnecessary
> globals, overly mysterious constants, odd variable names, unused
> variables, an unnecessary include and overly specific types. These are
> details though, and I'll explain the biggest issue I have with it later
> on.

Every time you post anything to me it's negative, and overtly so.
I'm to the point of ignoring your posts now from this point forward.

Please continue to post for others to read. They can learn from my
mistakes, and your chastising of me.

--
Rick C. Hodgin

PS -- Once again you've posted something to both comp.lang.c and
comp.lang.c++, but set the follow-up only to comp.lang.c.

Adam Wysocki

unread,
Jul 19, 2018, 8:25:49 AM7/19/18
to
In comp.lang.c Rick C. Hodgin <rick.c...@gmail.com> wrote:

> Somebody posted on comp.lang.asm.x86 an algorithm for fizz buzz.

There are many language tricks and hacks to make the solution interesting,
but I prefer solutions that are readable and simple enough to do the task.

The cleanest (definitely not the shortest) solution I could come up with
(in C++):

#v+
#include <boost/format.hpp>
#include <iostream>

static const unsigned MIN_NUMBER = 1;
static const unsigned MAX_NUMBER = 100;

/**
* \brief Check if value is divisible by another value
*
* \retval true Dividend is divisible by divisor
* \retval false Value is not divisible by divisor
*/

static inline bool isDivisible(unsigned dividend, unsigned divisor)
{
return !(dividend % divisor);
}

/**
* \brief Make word according to FizzBuzz rules
*
* Returns word according to FizzBuzz rules, that is:
*
* - if value is divisible by 3 and not by 5, returns "Fizz"
* - if value is divisible by 5 and not by 3, returns "Buzz"
* - if value is divisible both by 3 and 5, returns "Fizz Buzz"
* - as the last resort, returns string containing the value
*
* \param number Number to check
* \return String according to FizzBuzz rules
*/

static std::string makeWord(unsigned number)
{
std::string word;

if (isDivisible(number, 3))
word += "Fizz";

if (isDivisible(number, 5))
{
if (!word.empty())
word += " ";

word += "Buzz";
}

if (word.empty())
word = boost::str(boost::format("%u") % number);

return word;
}

int main()
{
for (unsigned i(MIN_NUMBER); i <= MAX_NUMBER; ++i)
{
const std::string suffix(i != MAX_NUMBER ? ", " : "\n");
std::cout << makeWord(i) << suffix;
}

return 0;
}
#v-

--
[ Adam Wysocki :: Warsaw, Poland ]
[ Email: a@b a=grp b=chmurka.net ]
[ Web: http://www.chmurka.net/ ]

Jorgen Grahn

unread,
Jul 25, 2018, 7:04:33 AM7/25/18
to
["Followup-To:" header set to comp.lang.c++.]

On Thu, 2018-07-19, Adam Wysocki wrote:
...
>
> /**
> * \brief Check if value is divisible by another value
> *
> * \retval true Dividend is divisible by divisor
> * \retval false Value is not divisible by divisor
> */

I really like it when people document what their functions do so I
don't have to guess or reverse-engineer the implementation, but I
can't help noticing the redundancy. Step 1:

/**
* \brief Check if value is divisible by another value
*
* \retval Whether dividend is divisible by divisor
*/

And since "check if ..." together with returning a bool makes it
obvious what the return value means, step 2:

/**
* \brief Check if value is divisible by another value
*/

Step 3 is noticing that you chose good names and "bool
isDivisible(dividend, divisor)" is pretty much the same text, so:

/**
*/

There wasn't anything missing in the documentation, as far as I can
tell. Except possibly "Undefined if divisor is 0", but if you know
what integer division is and how it's normally done in C or C++, you
already know what would happen.

> static inline bool isDivisible(unsigned dividend, unsigned divisor)
> {
> return !(dividend % divisor);
> }

I guess my message is: save the documentation for when it's needed.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Richard

unread,
Jul 25, 2018, 4:58:00 PM7/25/18
to
[Please do not mail me a copy of your followup]

Jorgen Grahn <grahn...@snipabacken.se> spake the secret code
<slrnplgm9m.31...@frailea.sa.invalid> thusly:

>I guess my message is: save the documentation for when it's needed.

This is why "Comments" are one of the code smells listed in
"Refactoring" by Martin Fowler.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Adam Wysocki

unread,
Jul 26, 2018, 5:16:58 AM7/26/18
to
In comp.lang.c Jorgen Grahn <grahn...@snipabacken.se> wrote:

> I really like it when people document what their functions do so I
> don't have to guess or reverse-engineer the implementation, but I
> can't help noticing the redundancy. Step 1:
>
> /**
> * \brief Check if value is divisible by another value
> *
> * \retval Whether dividend is divisible by divisor
> */

Could be (if we replace \retval with \return). It's Doxygen syntax (more
precisely: JavaDoc syntax, but used with Doxygen).

After running it through Doxygen it looks like this:

http://www.chmurka.net/r/usenet/fizzbuzz.png

The code is not visible here (and should not be), only this documentation
and prototypes.

Bo Persson

unread,
Jul 26, 2018, 8:35:41 AM7/26/18
to
Nice pictures, but it only confirms Jörgen's argument about the redundacy.

If the function is

bool is_X()

it pretty much tells us what the function does.

The description "Checks if X is true" and "returns true if X is true",
"returns false if X is false" just makes us read more text to verify
that it doesn't say something else. It doesn't help in any way.


Bo Persson



Rick C. Hodgin

unread,
Jul 26, 2018, 8:53:51 AM7/26/18
to
On Thursday, July 26, 2018 at 8:35:41 AM UTC-4, Bo Persson wrote:
> Nice pictures, but it only confirms Jörgen's argument about the redundacy.
>
> If the function is
>
> bool is_X()
>
> it pretty much tells us what the function does.
>
> The description "Checks if X is true" and "returns true if X is true",
> "returns false if X is false" just makes us read more text to verify
> that it doesn't say something else. It doesn't help in any way.

In this case it's redundant, but in other cases it may need to do
more to test if X is true. X may only be true in cases where it
is true AND we're not currently in some maintenance override mode,
or if the application's thread isn't suspended to save battery life,
etc. There may be more factors than a raw read and report. The
documentation here would give that information, up or down.

And, to be consistent with other documentation in the project, by
having such documentation here, it makes it an easy task to see
what's what quickly.

I like Doxygen. I think it's a little obtuse in some cases, but
what it provides is great. I have used such documentation rather
heavily on Java-based apps where it was built-in. I've used it
rarely in other software.

--
Rick C. Hodgin

David Brown

unread,
Jul 26, 2018, 9:29:16 AM7/26/18
to
On 26/07/18 14:53, Rick C. Hodgin wrote:
> On Thursday, July 26, 2018 at 8:35:41 AM UTC-4, Bo Persson wrote:
>> Nice pictures, but it only confirms Jörgen's argument about the redundacy.
>>
>> If the function is
>>
>> bool is_X()
>>
>> it pretty much tells us what the function does.
>>
>> The description "Checks if X is true" and "returns true if X is true",
>> "returns false if X is false" just makes us read more text to verify
>> that it doesn't say something else. It doesn't help in any way.
>
> In this case it's redundant, but in other cases it may need to do
> more to test if X is true. X may only be true in cases where it
> is true AND we're not currently in some maintenance override mode,
> or if the application's thread isn't suspended to save battery life,
> etc. There may be more factors than a raw read and report. The
> documentation here would give that information, up or down.

Yes, of course. If you can give a good enough description of the
function, its actions, its parameters and its return value by picking a
good name, then do so. If more information is needed, then document it.
I don't think anyone is arguing against useful comments - merely
against redundant ones.

It is a good general rule that if something can be described in the
language or the names of identifiers, then that is what you use. Only
resort to comments when necessary (but don't skimp on them if they /are/
necessary). Extra comments have a tendency to lose synchronisation when
the source code changes - information held in the source itself does not.

>
> And, to be consistent with other documentation in the project, by
> having such documentation here, it makes it an easy task to see
> what's what quickly.
>
> I like Doxygen. I think it's a little obtuse in some cases, but
> what it provides is great. I have used such documentation rather
> heavily on Java-based apps where it was built-in. I've used it
> rarely in other software.
>

I like doxygen too. As well as for commenting my own code, I have found
it useful for analysing existing code - set it up to document
/everything/ regardless of comments, and include caller, callee and
include graphs. It makes it easy to navigate around the code, see
cross-references, find messy parts, etc., using just a browser.

But what I don't like is when there is a documentation standard that
says you need big sections of doxygen commenting (or any commenting, for
that matter) for every little function or bit of code, so that you can't
find the real code in all the commentary.


Rick C. Hodgin

unread,
Jul 26, 2018, 10:30:10 AM7/26/18
to
That's one viewpoint. It's not the only one. And it's good practice
to err on the side of over-documenting if the documentation is also
clear and even obvious to some, because not everybody will be thinking
the way you were, or you do, when they read that. The little bit of
extra prompting might kick their brain cells into gear and get them
from where they are to where they need to be.

>> And, to be consistent with other documentation in the project, by
>> having such documentation here, it makes it an easy task to see
>> what's what quickly.
>>
>> I like Doxygen. I think it's a little obtuse in some cases, but
>> what it provides is great. I have used such documentation rather
>> heavily on Java-based apps where it was built-in. I've used it
>> rarely in other software.
>
> I like doxygen too. As well as for commenting my own code, I have found
> it useful for analysing existing code - set it up to document
> /everything/ regardless of comments, and include caller, callee and
> include graphs. It makes it easy to navigate around the code, see
> cross-references, find messy parts, etc., using just a browser.
>
> But what I don't like is when there is a documentation standard that
> says you need big sections of doxygen commenting (or any commenting, for
> that matter) for every little function or bit of code, so that you can't
> find the real code in all the commentary.

Yes. Yours is one viewpoint. I've also worked with/for people who
like to see documentation over code, because then even managers can
follow along with what it's doing.

Chocolate, vanilla and strawberry flavored ice cream. They all exist
for a reason. Not everybody likes your chocolate, David. A lot of
people do. And probably most people like it from time to time. But,
many people prefer vanilla, strawberry, or other, or if they're like
me and Captain Janeway, coffee-flavored ice cream (she's also from
Indiana you know, from a town about an hour south of where I live).

--
Rick C. Hodgin

Rick C. Hodgin

unread,
Jul 26, 2018, 10:38:02 AM7/26/18
to
On 7/26/2018 10:29 AM, Rick C. Hodgin wrote:
> That's one viewpoint.  It's not the only one.  And it's good practice
> to err on the side of over-documenting if the documentation is also
> clear and even obvious to some, because not everybody will be thinking
> the way you were, or you do, when they read that.  The little bit of
> extra prompting might kick their brain cells into gear and get them
> from where they are to where they need to be.

I'd also like to say that while I've never seen this before, and I don't
know why it doesn't exist, but I would like to see a debugger that has
the ability to single-step through comments. I don't always want to
step through code. I'd like to step through things like this:

// Open the record
// Is it valid?
// No, report error

Three lines of stepping, rather than this:

// Open the record
r = open_record(...);

// Is it valid?
if (r->isValid && r->data != NULL)
{
// No, report error
err = create_error_report(...);
log_error(err);
if (guiState->isUiActive)
present_error(err);
delete_error(err);
return;
}
// We're good

In many cases, I don't care about the details of what I'm debugging
because that code is working and I just want to get through it, so
I'd like to be able to switch between single-step mode, between the
comments, and between the actual code, and also between the assembly
underlying.

This is the concept behind my CFSCA concept (Comments, Flowchart,
Source Code, Assembly) that I incorporated into my Debi Debugger for
my Exodus operating system:

View in VLC if you can't view the video:
http://www.visual-freepro.org/videos/2014_02_13__exodus_debi_debugger.ogv

--
Rick C. Hodgin

David Brown

unread,
Jul 26, 2018, 10:51:59 AM7/26/18
to
That is a view that /sounds/ right - after all, if some documentation or
commenting is good, then surely more is better?

However, the reality is different. Documents and comments need to be
written and maintained - but they don't contribute directly to the
working of the code. So their maintenance is invariably given lower
priority than the code, and they quickly become something to fix when
you have time, rather than an integral part of development. They get
more and more separated from the reality of the code, and become
confusing, outdated, or even completely wrong. At this point they are
highly counter-productive.

Compare these two code snippets for scaling an analogue measurement from
a weighing system:

// Convert raw analogue input value into a weight measurement
// The reference weight is 5 kg, and it gives a reading of 4 volts.
double scale(double x) {
return x * 1.25;
}

vs.

double adc_to_weight_in_kg(double raw) {
const double referenceWeight = 5.0;
const double referenceReading = 4.0;

return x * referenceWeight / referenceReading;
}

What happens to the code when a more accurate check of the reference
weight gives 4.02 volts, found just before the system goes live? The
code gets changed to:

// Convert raw analogue input value into a weight measurement
// The reference weight is 5 kg, and it gives a reading of 4 volts.
double scale(double x) {
return x * 1.243781095;
}

vs.

double adc_to_weight_in_kg(double raw) {
const double referenceWeight = 5.0;
const double referenceReading = 4.02;

return x * referenceWeight / referenceReading;
}


Which do you prefer now - the one with the data in the code, or the one
with the comments?

You /could/ argue that you can have the data and names in the code,
/and/ comments. But then your final version would not be much better:

// Convert raw analogue input value into a weight measurement
// The reference weight is 5 kg, and it gives a reading of 4 volts.

double adc_to_weight_in_kg(double raw) {
const double referenceWeight = 5.0;
const double referenceReading = 4.02;

return x * referenceWeight / referenceReading;
}


Having /no/ comments is clearer, safer, and easier to maintain than
having the comments.


Of course, the correct balance between code and comments (or other
documentation) is going to vary significantly depending on the project,
its lifetime, its complexity, the development team, and many other
factors. I am not giving a "one size fits all" answer here - I am just
suggesting that it is something to think about, and comments are not
necessarily a helpful thing.

(No comments, /and/ poor choice of names and no indication of what is
going on is also a very bad idea - but I think everyone agrees on that!)


>>> And, to be consistent with other documentation in the project, by
>>> having such documentation here, it makes it an easy task to see
>>> what's what quickly.
>>>
>>> I like Doxygen. I think it's a little obtuse in some cases, but
>>> what it provides is great. I have used such documentation rather
>>> heavily on Java-based apps where it was built-in. I've used it
>>> rarely in other software.
>>
>> I like doxygen too. As well as for commenting my own code, I have found
>> it useful for analysing existing code - set it up to document
>> /everything/ regardless of comments, and include caller, callee and
>> include graphs. It makes it easy to navigate around the code, see
>> cross-references, find messy parts, etc., using just a browser.
>>
>> But what I don't like is when there is a documentation standard that
>> says you need big sections of doxygen commenting (or any commenting, for
>> that matter) for every little function or bit of code, so that you can't
>> find the real code in all the commentary.
>
> Yes. Yours is one viewpoint. I've also worked with/for people who
> like to see documentation over code, because then even managers can
> follow along with what it's doing.
>

I am not arguing against comments or documentation - I am arguing
against /unnecessary/ comments and documentation.


Rick C. Hodgin

unread,
Jul 26, 2018, 11:04:35 AM7/26/18
to
On 7/26/2018 10:51 AM, David Brown wrote:
> [snip]

I'm glad it works for you, David! (and those it works for)

We each need those things which make us do and be better in the
things we do. I'm happy for you, that you've found this solution
which is what you need. I encourage you toward those ends.

Be blessed.

--
Rick C. Hodgin

David Brown

unread,
Jul 26, 2018, 11:14:19 AM7/26/18
to
How about stepping through the code:

r = open_record(...);
if (!r->isValid()) {
report_error();
return;
}

Three things to step through, with as much information as the comments
were giving. And unlike your mix of code and comment, it actually does
what it says it should.

I fully realise that the error in your code above is just because it is
quickly typed sample code in a Usenet post, not real code. But it is
still an excellent demonstration of the problem. Your comments say "Is
it valid? No, report error", but the code is "Is it valid? Yes, report
error".


> In many cases, I don't care about the details of what I'm debugging
> because that code is working and I just want to get through it, so
> I'd like to be able to switch between single-step mode, between the
> comments, and between the actual code, and also between the assembly
> underlying.
>

Split your code into functions, and use "Step over", "Function step",
"Call step", or whatever term your debugger uses to run a complete
function in one step. That has been a standard debugging technique
since I first used a proper debugger some 25 years ago.

> This is the concept behind my CFSCA concept (Comments, Flowchart,
> Source Code, Assembly) that I incorporated into my Debi Debugger for
> my Exodus operating system:
>
> View in VLC if you can't view the video:
>
> http://www.visual-freepro.org/videos/2014_02_13__exodus_debi_debugger.ogv
>

(You know I am not going to be looking at that video. I am sure you are
happy with the tools you are making for yourself, but they are not
relevant to me nor to C++. I am happy to discuss comments in Usenet
posts, but not to go chasing videos. I know you like videos as a medium
for this sort of thing, but I do not.)

Rick C. Hodgin

unread,
Jul 26, 2018, 11:17:26 AM7/26/18
to
On 7/26/2018 11:14 AM, David Brown wrote:
> [snip]
I offered up my idea. If it's not for you then don't incorporate it
into your debugger.

Here are some other ones I've had:

http://www.libsf.org:8990/projects/LIB/repos/libsf/browse/ideas/debugger.txt

If they're not for you either, don't incorporate them into your
debugger.

-----
Be blessed in the things you do, David. I wish you the best.

--
Rick C. Hodgin

David Brown

unread,
Jul 26, 2018, 12:23:26 PM7/26/18
to
On 26/07/18 17:17, Rick C. Hodgin wrote:
> On 7/26/2018 11:14 AM, David Brown wrote:
>> [snip]
> I offered up my idea.  If it's not for you then don't incorporate it
> into your debugger.
>
> Here are some other ones I've had:
>
>
> http://www.libsf.org:8990/projects/LIB/repos/libsf/browse/ideas/debugger.txt
>
>
> If they're not for you either, don't incorporate them into your
> debugger.
>

I am not writing a debugger - I am just telling you how to get the
effect you are describing using existing tools.


David Brown

unread,
Jul 26, 2018, 12:34:42 PM7/26/18
to
On 26/07/18 17:04, Rick C. Hodgin wrote:
> On 7/26/2018 10:51 AM, David Brown wrote:
>> [snip]
>
> I'm glad it works for you, David! (and those it works for)
>
> We each need those things which make us do and be better in the
> things we do.  I'm happy for you, that you've found this solution
> which is what you need.  I encourage you toward those ends.
>

I am not talking about a personal preference like flavours of ice cream.

Imagine a line with development practices like "write clear code" and
"test your code" on the far left - things that are considered standard
practice for any serious programmer. And on the far right, you have
things like "use camelCase" or "use underscores" - things that are
purely a stylistic preference.

Avoiding unnecessary comments and preferring to write things in code
rather than comments is a good way to the left on that line. It is
perhaps similar to "indent consistently" or "break your code into
manageable pieces". It is the kind of thing that most serious,
experienced programmers will agree on, regardless of language.

Exactly how much documentation or commentary is necessary or appropriate
will vary tremendously depending on the project, the team, the
requirements, the code complexity, etc.

This is clearly something that /you/ should adopt, as demonstrated
accidentally by your example for debugging code.

(Please don't take this as personal criticism - these recommendations
are for everyone who programs.)


Rick C. Hodgin

unread,
Jul 26, 2018, 12:35:31 PM7/26/18
to
Ah...

Then it shouldn't affect you very much because you have a system that
works well for you, and I'm glad about that. I like when people have
thing which prop them up in this world. We all need things like that.

--
Rick C. Hodgin

Rick C. Hodgin

unread,
Jul 26, 2018, 12:38:36 PM7/26/18
to
On 7/26/2018 12:34 PM, David Brown wrote:
> On 26/07/18 17:04, Rick C. Hodgin wrote:
>> On 7/26/2018 10:51 AM, David Brown wrote:
>>> [snip]
>>
>> I'm glad it works for you, David! (and those it works for)
>>
>> We each need those things which make us do and be better in the
>> things we do.  I'm happy for you, that you've found this solution
>> which is what you need.  I encourage you toward those ends.
>
> I am not talking about a personal preference like flavours of ice cream.

Oh...

My mistake. Please forgive my ignorance.

--
Rick C. Hodgin

David Brown

unread,
Jul 26, 2018, 1:47:43 PM7/26/18
to
No problem. But I'd suggest you re-read some my posts in this thread,
and see if it changes your mind about what I've been saying. I suspect
you will either see the benefit in what I have been saying and learn
from it, or find that you misunderstood what I wrote (maybe I wasn't
clear) and agree with it all along.

However, if you still think it is a reasonable choice to use comments
instead of writing clear code with good names, and are happy to have
your comments say one thing and the code say something significantly
different, or if you work for the department of redundancy department,
then fair enough.

Rick C. Hodgin

unread,
Jul 26, 2018, 2:08:12 PM7/26/18
to
On 7/26/2018 1:47 PM, David Brown wrote:
> No problem.  But I'd suggest you re-read some my posts in this thread...

You really don't get it do you, David?

People are complex. Applications of the things that exist are nuanced.
There's more than one solution to nearly everything that exists, and
here's more than one time things will be appropriate or not. There's
some times things will have some value, and other times they will not.

I agree with "your" points in some areas, but not all. And on the
whole, I disagree with you on almost everything related to software
development. Where we do overlap it's from my own personal experience
in things and not from your teaching, as there are some things which
are fundamental and they exist regardless of anyone's point of view.
This disparity between us in beliefs is long-established between us
over years, and I'm content with that.

I'm also content to be where I am and I offer up the things I do to
help other people with those things I have interest or inspiration in.

It's my offering unto God first, people second, and there's not one
soul anywhere under any obligation to take the things I offer and use
them ... but I give them over to people so they can use them if they
choose to do so.

--
Rick C. Hodgin

Jorgen Grahn

unread,
Jul 27, 2018, 4:16:35 AM7/27/18
to
On Thu, 2018-07-26, Adam Wysocki wrote:
> In comp.lang.c Jorgen Grahn <grahn...@snipabacken.se> wrote:
>
>> I really like it when people document what their functions do so I
>> don't have to guess or reverse-engineer the implementation, but I
>> can't help noticing the redundancy. Step 1:
>>
>> /**
>> * \brief Check if value is divisible by another value
>> *
>> * \retval Whether dividend is divisible by divisor
>> */
>
> Could be (if we replace \retval with \return). It's Doxygen syntax (more
> precisely: JavaDoc syntax, but used with Doxygen).

Ok. I use Doxygen too, but don't like its \tags. It may be a quirk in
my personality, but I prefer documenting as a paragraph of text, in
the same style and tone that typical Unix man pages uses under
DESCRIPTION. A good (and fairly complex) example is the Linux
strtol(3) manual page.

I find that most of the time, if I write that text well, the parameter
and return value lists become superfluous.

Doxygen supports that style too.

IME, documentation using \param and \return often ends up as a list of
tautologies and still doesn't explain what the function does. I think
that's because an author who isn't really interested in documentation
can get away with doing it mechanically, like filling in a table.

(That doesn't apply to you; you're obviously interested in correct and
complete documentation.)

Then, to be complete, I should mention that if I design my classes
well and document them as needed, often the related functions need no
documentation at all.

> After running it through Doxygen it looks like this:
>
> http://www.chmurka.net/r/usenet/fizzbuzz.png
>
> The code is not visible here (and should not be), only this documentation
> and prototypes.

I sometimes wonder how often people read the Doxygen-generated
documentation, as opposed to reading the comments in the source. I
tend to end up doing the latter. Sometimes I read both, but only use
Doxygen as an index, and as a tool to visualize class diagrams and
#include hierarchies.

Jorgen Grahn

unread,
Jul 27, 2018, 4:19:46 AM7/27/18
to
On Thu, 2018-07-26, Rick C. Hodgin wrote:
> On Thursday, July 26, 2018 at 8:35:41 AM UTC-4, Bo Persson wrote:
>> Nice pictures, but it only confirms Jörgen's argument about the redundacy.
>>
>> If the function is
>>
>> bool is_X()
>>
>> it pretty much tells us what the function does.
>>
>> The description "Checks if X is true" and "returns true if X is true",
>> "returns false if X is false" just makes us read more text to verify
>> that it doesn't say something else. It doesn't help in any way.
>
> In this case it's redundant, but in other cases it may need to do
> more to test if X is true. X may only be true in cases where it
> is true AND we're not currently in some maintenance override mode,
> or if the application's thread isn't suspended to save battery life,
> etc. There may be more factors than a raw read and report. The
> documentation here would give that information, up or down.

To me, that's part of the reason not to document this function: then
the reader knows something non-obvious is happening when she
encounters that other function.

Rick C. Hodgin

unread,
Jul 27, 2018, 10:17:27 AM7/27/18
to
I agree ... in some cases. It depends on how this one function exists
in the rest of the system. If everything is documented a particular
way, then to document it commensurately is appropriate. For a tiny
standalone app like this, it's unnecessary.

That's an example of the variation and nuance required to understand
when to apply documentation, and when not to. Universal or blanket
statements about how to document things are ill-effective and ill-
advised. It depends on a great many factors, but on the whole, I tend
to lean to the side of over-documenting, because it doesn't hurt, and
I also type very fast. :-)

--
Rick C. Hodgin

0 new messages