0

By mistake I used the following function in MPI -

double f(x) {
  return(4.0/(1 + x*x));
}

Notice that I have not declared the data type of x in the above code.

And then compiled it using :

mpicc q.c -o q

Still the program does not throw an error and compiles successfully.

And on using a wrapper, I get the following values of f -

f(2) = 0.8

f(1) = 2

How is this working without an error?

97amarnathk
  • 957
  • 2
  • 11
  • 30

2 Answers2

2

In old style C any declared with name but without type variable has a type of int. So fuction will take integer argument, and in expression it will be promoted to double.

UPDATE

In the pre-standard version of C and in the first standardized version C89 variable declared without type was of type int by default. Such behavior was removed in C99 and consecutive standards. One can read about it in the Kernigan&Ritchie book C Programming Language, 2nd Edition.

Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64
  • Oh. That's interesting. I did not know that. Is there a source where I can read this stuff up? – 97amarnathk Nov 09 '17 at 17:36
  • @97amarnathk It was in pre-standard and in first standard of C language - C89 (adopted in 1989 as you could surmise). It was removed in all consecutive C standards. I read it in the famous C book from K&R: https://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628 – Severin Pappadeux Nov 09 '17 at 17:42
  • Oh nice. Will read that. I am accepting your answer :). Also it would be helpful if you add this link in the answer itself. Thanks. – 97amarnathk Nov 09 '17 at 17:44
  • @97amarnathk Done – Severin Pappadeux Nov 10 '17 at 02:09
  • 1
    That's not quite correct. An undeclared variable was an error. A old-style function declaration let you declare the name, but not the type, of a parameter; the type would default to `int`. In C99 and later, old-style function declarations are still permitted, but you must declare the type; the "implicit `int`" rule was dropped. – Keith Thompson Nov 10 '17 at 02:18
2
double f(x) {
  return(4.0/(1 + x*x));
}

This compiles because (a) C still permits some old features that are considered obsolescent, and (b) you're not asking your compiler to enforce the current version of the language.

In modern C, a function should be declared/defined with a prototype, a declaration that specifies the types of any parameters:

double f(int x) {
    /* ... */
}

Pre-ANSI C (prior to 1989) didn't support prototypes, and function parameters were defined with a different syntax. For example, you could write:

double f(x)
int x;
{
    /* ... */
}

The type of the parameter was not visible to callers, so calling f with an argument of a type other than int could have unpredictable results. (This was obviously a problem, which is why prototypes were introduced.) Furthermore, you could omit the int x; line and the type would default to int. And you could omit the double return type and that would also default to int.

Old-style declarations are still permitted, but it's rarely a good idea to use them. The implicit int rule was dropped in the 1999 standard.

You should find out how to ask your compiler to enforce the rules of modern C. If you're using gcc, then gcc -std=c11 -pedantic is a good start.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631