1

Is it wrong to define keyword-like macros if they improve code readability?

For Example, the IMPLICIT macro:

#define IMPLICIT /* IMPLICIT constructor(parameters...); */

struct X
{
    explicit X();
    IMPLICIT X(int i);
    IMPLICIT X(std::sting s);
    explicit X(const char* ch);
};

Instead of:

struct X
{
    explicit X();
    X(int i);
    X(std::sting s);
    explicit X(const char* ch);
};

CONSIDERATION: Regardless of the code readability, the definition of the IMPLICIT macro can be changed to simply disable all implicit constructors or ..., for future maintains.

EDIT: My example is not important, my question isn't specific to it, and I removed the block macro example.

halfer
  • 19,824
  • 17
  • 99
  • 186
Sadeq
  • 7,795
  • 4
  • 34
  • 45
  • 6
    But you are not improving code readability. – juanchopanza Aug 24 '14 at 16:06
  • I'm voting to close this as "primarily opinion based" because that's subjective.. in fact I agree with juanchopanza and that seems horrible to me – Marco A. Aug 24 '14 at 16:07
  • Those are only an example, sometimes they can improve code readability. – Sadeq Aug 24 '14 at 16:07
  • 2
    They don't improve readability because the reader needs to go find the definition of the macro before continuing. Macros and their names cannot be trusted. – Thomas Matthews Aug 24 '14 at 16:08
  • I have a hard time imagining a situation in which this would help readability. The examples you give clearly hurt it. – Jerry Coffin Aug 24 '14 at 16:09
  • 1
    Macros that simplify or clarify code can be helpful, especially if they assist with something that's repeatedly done in a specific project - encapsulating a common error-handling strategy, etc. These examples are insane, though, so it's hard to answer specifically (disclaimer or no). – Paul Roub Aug 24 '14 at 16:11
  • Put another way: you assert that "sometimes they can improve code readability". If that's true (as might be shown by *very* different examples), who would argue against improved readability? – Paul Roub Aug 24 '14 at 16:14
  • 2
    It depends. The macros above are horrible, adding verbosity and risking name conflicts. But macros that greatly reduce verbosity, ensapsulating boiler plate code that in practice cannot be abstracted, are OK in my view, provided you use ALL UPPERCASE names and a relatively unique prefix. – Cheers and hth. - Alf Aug 24 '14 at 16:16
  • @PaulRoub: Even if i used keyword-like macros to improve code readability (but forget my examples), is it still justifiable? – Sadeq Aug 24 '14 at 16:18
  • *"Is it a bad practice to define keyword-like macros just for improving code readability?"* - Yes. Exceptions prove the rule. Your macros, however, do not seem to be such an exception. – Christian Hackl Aug 24 '14 at 16:46

4 Answers4

4

Defining keyword-like macros just for improving code readablity

I think its acceptable. But like Marco said, its fairly subjective.


I think an example of a macro enhancing readability is C++ and NOTHROW. Oddly, specifying throw() means a function does not throw; and opposed to throw (SomeException), which means a function could throw an exception. There's nothing intuitive about declaring something throw() when it does not throw.

Lots of chatter about it on Stack Overflow:


Microsoft defines IN, OUT and INOUT to help with readability and usability. The macros decorate function parameters and are defined to nothing. For example, you might see (I don't have a specific Microsoft example handy):

// Process foo. Reuse baz if possible; reallocate if needed and return size.
// Return TRUE/FALSE as success/failure. Return an error code if result is FALSE.
int FooBarBaz(IN char* foo, IN int flen, INOUT char** baz, INOUT int* blen, OUT int* err);

Related: macros are helpful to abstract platform differences. For example, exporting a function from a shared object (Unix and knock-offs) or dynamic link libraries (Windows).


Related: macros are helpful to abstract configuration differences. For example, the meaning or implementation of ASSERT in debug and release configurations.


Related: hijacking keywords can be helpful. For example, re-defining C++'s protected and private to public can be helpful during testing so a test case can be written against methods that aren't normally accessible.

Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
2

As stated your macros don't enhance readability. Somebody may be wondering what BLOCK or IMPLICIT means, thinking they perform some special function, when in fact they do not. It seems better suited for a comment or refactoring. In IDEs like Visual Studio, you have the ability to fold lines of code (hide/show them) or to group them into documentation blocks (i.e., #REGION). Macros that don't do nothing just add noise to your code.

1

My best macro is a logging macro:

#define SYSTEM_FAILURE(code, comment) \
{ \
    System_Failure(code, comment, __FILE__, __FUNCTION__, __LINE__); \
}

The macro is the easiest method to plug in the filename, function name and line number of where the failure was encountered.

Other than this macro, there are none in our shop.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

Difficult to find good examples, where macros that are used to improve readability could not be avoided.

This is the best example that I could come up with (from the Linux kernel):

#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

Example:

struct book {
  char title[100];
  char author[100];
};

// ...
printf("%lu\n", FIELD_SIZEOF(struct book, title)); // prints 100

(I don't know if this macro can be avoided in C++.)

Beside that I think macros can sometimes improve readability when they are used for code generation to eliminate boilerplate code.

Philipp Claßen
  • 41,306
  • 31
  • 146
  • 239