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

ifdef and loss of readability

40 views
Skip to first unread message

alessio211734

unread,
Apr 11, 2021, 2:19:19 PM4/11/21
to
Hello,
I'm saving all iterations of an algorithm to a file for debugging later. I would like to save this information only in the debug/test phase so that I used a macro.
But inserting so many macros makes the code lose its readability

example:

void myclass::myAlgorithm()
{
// here code algorithm
....
#ifdef TEST_ALGORITHM
iters.iterations.push_back(iteration);
...
#endif
// here code algorithm
....
#ifdef TEST_ALGORITHM
iters.save(datafile);
...
#endif
// here code algorithm
....
}

My code lose of readability but i don't know how to get around this problem.

Lew Pitcher

unread,
Apr 11, 2021, 2:51:17 PM4/11/21
to
On Sun, 11 Apr 2021 11:19:13 -0700, alessio211734 wrote:

> Hello,
> I'm saving all iterations of an algorithm to a file for debugging later.
> I would like to save this information only in the debug/test phase so
> that I used a macro.
> But inserting so many macros makes the code lose its readability
>
> example:
>
> void myclass::myAlgorithm()
> {

Not C. Not topical in comp.lang.c

> // here code algorithm
> ....
> #ifdef TEST_ALGORITHM
> iters.iterations.push_back(iteration);
> ...
> #endif
> // here code algorithm
> ....
> #ifdef TEST_ALGORITHM
> iters.save(datafile);
> ...
> #endif
> // here code algorithm
> ....
> }
>
> My code lose of readability but i don't know how to get around this
> problem.

Patient: "Doctor. It hurts when I do this."
Doctor: "So, don't do that."

Look into a source-code management tool. Checkpoint each iteration of
your code (as a separate code version) into the management tool. You
should be able to diff versions to come up with a list of what changed,
and revert your code to a previous version if you wind up following a
blind alley.

HTH
--
Lew Pitcher
"In Skills, We Trust"
Message has been deleted

Richard Harnden

unread,
Apr 11, 2021, 4:05:38 PM4/11/21
to
On 11/04/2021 20:06, alessio211734 wrote:
> Hello,
> I'm saving all iterations of an algorithm to a file for debugging later.
> I would like to save this information only in the debug/test phase so
> that I used a macro.
> But inserting so many macros makes the code lose its readability
>
> example:
>
> void myclass::myAlgorithm()
> {
>
> // here code algorithm
> ....
> #ifdef TEST_ALGORITHM
> iters.iterations.push_back(iteration);
> ...
> #endif
> // here code algorithm
> ....
> #ifdef TEST_ALGORITHM
> iters.save(datafile);
> ...
> #endif
> // here code algorithm
> ....
> }
>
> My code lose of readability but i don't know how to get around this
> problem.
>

Google groups can't handle '++'s ... get a proper newsreader.

Manfred

unread,
Apr 11, 2021, 4:05:53 PM4/11/21
to
On 4/11/2021 8:19 PM, alessio211734 wrote:
> Hello,
> I'm saving all iterations of an algorithm to a file for debugging later. I would like to save this information only in the debug/test phase so that I used a macro.
> But inserting so many macros makes the code lose its readability

One direct mitigation might be:

#ifdef TEST_ALGORITHM
#define DEBUG_ONLY(x) x
#else
#define DEBUG_ONLY(x)
#endif

...

DEBUG_ONLY(iters.iterations.push_back(iteration));

...

However, I have a similar objection as Lew's, in that I think this is
just too much debug code that is injected into the source.
I'd go for a proper unit test design instead.

(and yes, if you use c++, post to comp.lang.c++)

>
> example:
>
> void myclass::myAlgorithm()
> {
> // here code algorithm
> ....
> #ifdef TEST_ALGORITHM

Malcolm McLean

unread,
Apr 11, 2021, 4:56:57 PM4/11/21
to
On Sunday, 11 April 2021 at 19:19:19 UTC+1, alessio211734 wrote:
>
>
> My code lose of readability but i don't know how to get around this problem.
>
Declare a regular variable, test_algorithm.

Then if you insist you can have one #ifdef to set it.

Now wrap the conditionals in a regular if() block. Much less visually distracting.

Chris M. Thomasson

unread,
Apr 11, 2021, 5:30:18 PM4/11/21
to
On 4/11/2021 12:06 PM, alessio211734 wrote:
> Hello,
> I'm saving all iterations of an algorithm to a file for debugging later.
> I would like to save this information only in the debug/test phase so
> that I used a macro.
> But inserting so many macros makes the code lose its readability
>
> example:
>
> void myclass::myAlgorithm()
> {
>
> // here code algorithm
> ....
> #ifdef TEST_ALGORITHM
> iters.iterations.push_back(iteration);
> ...
> #endif
> // here code algorithm
> ....
> #ifdef TEST_ALGORITHM
> iters.save(datafile);
> ...
> #endif
> // here code algorithm
> ....
> }
>
> My code lose of readability but i don't know how to get around this
> problem.
>

Wrt to C, a long time ago, I remember using the rather simple pattern,
pseudo-code typed in newsreader so sorry for typos:
___________________________

// variant 0
struct algo_0
{
int foo;
};

int algo_0_create(struct algo_0* self, ...)
{
return true or false based on any failure
}

void algo_0_destroy(struct algo_0* self)
{
...;
}



// variant 1
struct algo_1
{
int foo;
int bar;
};

int algo_1_create(struct algo_1* self, ...)
{
return true or false based on any failure
}

void algo_1_destroy(struct algo_1* self)
{
...;
}




// Abstract the API


// default variant
#if ! defined(ALGO)
#define ALGO 0
#endif


#if ALGO == 0

typedef struct algo_0 algo;
#define algo_create algo_0_create
#define algo_destroy algo_0_destroy

#elif ALGO == 1

typedef struct algo_1 algo;
#define algo_create algo_1_create
#define algo_destroy algo_1_destroy

#else
#error FOOBAR
#endif
___________________________




Now, we have an abstract API:

algo_create
algo_destroy

Kaz Kylheku

unread,
Apr 11, 2021, 9:10:38 PM4/11/21
to
Indentation? If yu had a run-time variable, it would be this:


void myclass::myAlgorithm()
{
// here code algorithm
....

if (test_algorithm) {
iters.iterations.push_back(iteration);
...
}
// here code algorithm
....

if (test_algorithm) {
iters.save(datafile);
...
}

// here code algorithm
....
}

You can indent #ifdefs similarly.

void myclass::myAlgorithm()
{
// here code algorithm
....

#ifdef TEST_ALGORITHM
iters.iterations.push_back(iteration);
...
#endif
// here code algorithm
....

#ifdef TEST_ALGORITHM
iters.save(datafile);
...
#endif

// here code algorithm
....
}

Nested #if/#ifdef directives without indentation can be hard to follow.

Another readabiilty barrier is to avoid flipping between #ifdef
and #ifndef. It's hard to grok that "n" in the middle of #ifndef.

A good practice is to use the value 1 for true, and then use #if
to test it.

#if TEST_ALGORITHM

then if you need #ifndef TEST_ALGORITHM, somewhere, you instead use

#if !TEST_ALGORITHM

This will work even if TEST_ALGORITHM is not defined. The preprocessor
treats undefined identifiers in expressions as being 0.

You can use a compile-time constant and if statements, by the way.
Any viable compiler from the last 30 years will remove the dead code.

if (TEST_ALGORITHM) { // must be defined as 0 or 1
// code here is dead if TEST_ALGORITHM is 0.
}

and the nice thing is that the interior still has to compile.

The useful thing about #ifdef is that the code in between,
when it is deselected, does not have to be compilable.

#ifdef WIN32
HANDLE foo = SomeFunctionOnlyOnWindowsEx(arg, ...)
...
#endif

When WIN32 is absent, the compiler does not see this, which is a good
thing because the function would not be declared or defined!

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
0 new messages