Syntactic sugar in C/C++

13,862

Solution 1

The way you did it seems to me the correct way to do it, if you're going to do it at all. Because the expansion of the macro is so similar to what you'd expect[1], I think it's valid to make the macro look like syntax (), rather than the usually recommended SCARY_UPPERCASE_MACROS() which are used to show that this code doesn't follow usual syntax and you should only use it carefully.

[1] The only flaw being the inability to declare variables, which is unlikely anyway, and likely to produce an error in the right place when used incorrectly, rather than doing something weird.

Furthermore, even small increases in readability are important, so being able to say until ( instead of while (! really does make it easier to read many loops. If the ending condition is more easily thought of as an exceptional condition (regardless of whether it is or not) writing the loop that way round makes it easier to read. So even though it is only syntactic sugar, I think there's reason to consider it.

However I don't think it's worth it. The benefit is small, since most programmers are used to reading if (! and the cost is real: Anyone reading the code will have to check whether this a macro, or a custom compiler, and whether or no it does what they think. And it may misleadingly make you think you can do things like i=5 unless xxxx;. Such little improvements, if widespread, would fragment the language, so often it's best to do things the standard way, and adopt improvements slowly.

However, it can be done well: the entirety of boost and tr1, especially the stuff done with templates to look like extensions to the library, involves extending C++ in various ways, many of which aren't adopted as they didn't seem worth it, but many of which have small or very widespread take-up because they made real improvements.

Solution 2

Can anyone suggest a better alternative?

Yes. Don't do this at all. Just use the while and if statements directly.

When you're programming in C or C++, program in C or C++. While until and unless might be used frequently and idiomatic in some languages, they are not in C or C++.

Solution 3

This reminded me of something I have seen in someone's code:

#define R return;

Besides, making the code hard to comprehend, you increase maintenance costs.

Solution 4

I suggest it would be better not use them.

You cannot use them in Ruby style as

`printf("hello,world") unless(a>0);`

is illegal.

And it would be more difficult for C programmers to understand the code. Meanwhile the extra macro could be a problem.

Solution 5

I don't think your macros are bad in particular if they are used only in your own code base. This article might be interesting for you. That being said, I see some downsides in your macros when we use them in C++.
For example, we cannot write as:

until (T* p = f(x)) ...
unless (T* p = f(x)) ...

on the other hand, we can write as:

while (T* p = f(x)) ...
if (T* p = f(x)) ...

As for unless, if we define it as:

#define unless(x) if (x) {} else

then we can write unless (T* p = f(x)) .... However, in this case we cannot add else clause after it.

Share:
13,862
BiGYaN
Author by

BiGYaN

I attack everything in life with a mix of extraordinary genius and naive incompetence; it is often difficult to tell which is which :P Presently I'm a student pursuing ME in CSE from IISc, India. I intend to specialize in Machine Learning techniques for large scale data. Usually I use C/C++ and occasionally Java to code along with Matlab. Of lately I have been fiddling around with Python, which seems to have brought back the "fun" part in programming.

Updated on June 05, 2022

Comments

  • BiGYaN
    BiGYaN almost 2 years

    I have been looking into Ruby and find its keywords "until" and "unless" very interesting. So I thought what was a good way to add similar keywords into C/C++. This is what I came up with:

    #define until(x)    while(!(x))
    #define unless(x)   if(!(x))
    

    I am looking for some suggestions on this. Can anyone suggest a better alternative?

    Here is an example of a program that I wrote to illustrate what I intended to do:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define until(x)    while(!(x))
    #define unless(x)   if(!(x))
    
    unsigned int factorial(unsigned int n) {
        unsigned int fact=1, i;
        until ( n==0 )
            fact *= n--;
        return fact;    
    }
    
    int main(int argc, char*argv[]) {
        unless (argc==2)
            puts("Usage: fact <num>");
        else {
            int n = atoi(argv[1]);
            if (n<0)
                puts("please give +ve number");
            else
                printf("factorial(%u) = %u\n",n,factorial(n));
        }
        return 0;
    }
    

    It would be great if you could point me to some references for similar tricks that can be employed in C or C++.