C and and and iso646.h

During some research for my day job, I was pointed to a utility written by Guillaume Dargaud that converts LabWindows/CVI user interface files (.uir) over to HTML so they can run in a web browser instead of as a Windows UI app. The program, written in C, can be found here:

https://www.gdargaud.net/Hack/PanelToCgi.html

https://gitlab.com/dargaud/PanelToForm

But that is not really what this post is about. Instead, it is about seeing lines in his code (originally created in 2000) like this:

Active = Mode!=VAL_INDICATOR and Visible and !Dimmed;

if (Fmin<-1e30 and Fmax>1e30) {

if (Dmin<-1e30 and Dmax>1e30) {

That looked more like Visual BASIC or something than C to me. “and”? Shouldn’t that be “&&” in C for a logical and?

I mentioned this in the forum post where I learned of this utility, and received this response:

“It’s been standard C since the introduction of #include <iso646.h> in the 90s. I always found it more readable this way.”

– gdargaud, via https://forums.ni.com/t5/LabWindows-CVI/LabWindows-UI-to-ncurses-Linux-macOS-terminal/m-p/4472028

iso646.h

This one is new to me. Wikipedia has a page about it:

https://en.wikipedia.org/wiki/C_alternative_tokens

Here is what that header file looks like on the Microchip MPLAB PIC24 compiler:

#ifndef _ISO646_H
#define _ISO646_H

#ifndef __cplusplus

#define and &&
#define and_eq &=
#define bitand &
#define bitor |
#define compl ~
#define not !
#define not_eq !=
#define or ||
#define or_eq |=
#define xor ^
#define xor_eq ^=

#endif

#endif

Have you ever seen this used in the wild? I was surprised to see it even supported in a non-mainstream compiler, like that one.

Looking at the list, this line could have been changed further:

Active = Mode not_eq VAL_INDICATOR and Visible and not Dimmed;

And indeed, that works:

#include <stdio.h>
#include <iso646.h>

// #define and    &&
// #define and_eq &=
// #define bitand &
// #define bitor  |
// #define compl  ~
// #define not    !
// #define not_eq !=
// #define or     ||
// #define or_eq  |=
// #define xor    ^
// #define xor_eq ^=

#define VAL_INDICATOR 1

int main()
{
    int Active = 0;

    int Mode = (VAL_INDICATOR + 1);
    int Visible = 1; // Visible
    int Dimmed = 1; // Dimmed
    
    printf ("Mode: %d  Visible: %d  Dimmed: %d\n", Mode, Visible, Dimmed);
    
    Active = Mode not_eq VAL_INDICATOR and Visible and not Dimmed;
    
    printf ("Active: %d\n", Active);
    
    Mode = (VAL_INDICATOR + 1);
    Visible = 1; // Visible
    Dimmed = 0; // NOT Dimmed
    
    printf ("Mode: %d  Visible: %d  Dimmed: %d\n", Mode, Visible, Dimmed);
    
    Active = Mode not_eq VAL_INDICATOR and Visible and not Dimmed;
    
    printf ("Active: %d\n", Active);

    return 0;
}

Coding standards such as the BARR-C Embedded Coding Standard specifically say not do do things like this since it makes the code harder to figure out since the user has to go look up what those defines are really set to. Imagine how the code might look fine, but be complete wrong, if a define were messed ;-)

Have you seen this? Do you do this? Leave a comment…

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.