Question: When you see a line like:

```
#define IX(i,j) ((i)+(N+2)*(j))

```

is that equivalent to:

```
int IX(int i, int j) {

    return ((i)+(N+2)*(j));

}

```

How do you know the return type etc?

Answer: 
Macros never get seen by the compiler - the preprocessor replaces the text.

So, when you write:

```
result = IX(5, 3);
```

The compiler will see this:

```
result = ((5)+(N+2)*(3));
```

This can have impacts on behaviour, but it depends on your macro. In this case, not so much (there are also performance and debugging differences, but let's not worry about them here).

Had, for example, you defined your macro like this (note second use of *i* variable)

```
#define IX(i,j) ((i)+(i+2)*(j))
```

And called it like so:

```
result = IX(++i, j);
```

Then the macro and function would have different behaviour.
No, it's not equivalent. A `#define` is a macro, a kind of source code string substitution capability.

Your example of an `IX()` function has many attributes relevant to executing code, like having instructions compiled once, having an address, and requiring integer parameters.

The macro takes parameters, but it has no type handling, until the arithmetic is attempted. Even then, any parameters which the preprocessor can evaluate could do something useful. Or it could do something unexpected.

As a handy rule of thumb, the more that macros are used, the less understandable and maintainable the code tends to be.