2

This is the popular bash command cat written in C.

I have no idea what this line does:

if (argc==1) return cat(stdin), 0;

I've never seen anything like it before. Here's the complete code:

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

static void cat(FILE *f)
{
        int     c;

        while (EOF != (c = getc(f)))
        {
                if (EOF == putchar(c))
                {
                        perror("cat");
                        return;
                }
        }
        if (ferror(f))
        {
                perror("cat");
                return;
        }
}

int main(int argc, char **argv)
{
        if (argc==1) return cat(stdin), 0;
        for(int i=1; i<argc; i++)
        {
                if (!strcmp("-", argv[i]))
                {
                        cat(stdin);
                        continue;
                }
                FILE *f = fopen(argv[i], "r");
                if (!f)
                {
                        perror("cat");
                        continue;
                }
                cat(f);
                fclose(f);
        }
        return 0;
}

What does the line if (argc==1) return cat(stdin), 0; do?

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
Heirloom
  • 25
  • 6

1 Answers1

6

This:

cat(stdin), 0

is a comma expression. This kind of expression evaluates all the operands (separated by commas) in order from left to right, with an implicit sequence point at each comma, and finally returns the value of the rightmost operand (in this case 0).

As an example, here:

int x = (1, 2, 3, 4);

the variable x assumes the value 4. There are cases in which the expression needs to be parenthesized to avoid ambiguity (e.g. like I just did above) and cases in which it is not needed (e.g. after return).

All in all, there are very few cases in which a comma expression makes sense, and this certainly isn't one of them. The code you show could be rewritten as:

if (argc == 1) {
    cat(stdin);
    return 0;
}

Using return cat(stdin), 0; simply executes cat(stdin) before returning 0. It's a silly "trick" to make the code fit in one line.

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128