1
int h, i; 
void B(int w) {
    int j, k;
    i = 2 * w;
    w = w + 1;
    ...
}
void A(int x, int y) { 
    float i, j;
    B(h); 
    i = 3;
    ... 
}
int main() {
    int a, b;
    h = 5; a = 3; b = 2;
    A(a, b);
    B(h);
    return 0;
}

As far as the modern compilers are concerned, I find that function A() is not allowed to call function B(). I find the same with compiler like gcc and turboc.

I have heard from my Prof. that standard C allows B() to call A() and vice-versa, with the same code. Is it true?

Where can I find more info regarding actual concepts of standard C?

chqrlie
  • 131,814
  • 10
  • 121
  • 189
itsme.cvk
  • 123
  • 1
  • 8
  • 1
    Your prof is right. Perhaps try it – Ed Heal Mar 01 '16 at 19:38
  • 1
    I wonder whether this is called *top-down*. *Top-down* usually means that you start solving the problem by writing the function that solves the problem, but calls functions that you later declare. In contrast to *bottom-up* where you first define functions to solve the *sub*-problems. – Willem Van Onsem Mar 01 '16 at 19:39
  • 4
    "I know that function `A()` cannot call function `B()`" - Why do you *know* that? – Amit Mar 01 '16 at 19:39
  • As an aside, don't use `void main`. `main` should return an `int` – R_Kapp Mar 01 '16 at 19:39
  • @EdHeal: No, **standard** C requires a declaration preceeding since C99, if the function. Do you mean classical K&R C? – too honest for this site Mar 01 '16 at 19:42
  • 1
    As the code stands (ie. there are no function prototypes), he is correct about `B()` not being able to call `A()`. I think his question is whether `A()` can call `B()` *without* requiring function prototypes at the beginning of the code in Standard C. – callyalater Mar 01 '16 at 19:42
  • @callyalater: That's what the OP says in the question, but that's backwards: `B` is defined before `A`, therefore `A` can call `B` (with or without prototypes). Without a function prototype, though, `B` cannot call `A`. – R_Kapp Mar 01 '16 at 19:45
  • @R_Kapp: Thanks, I really wondered if I missed something. – too honest for this site Mar 01 '16 at 19:46
  • "Where can I find more info regarding actual concepts of standard C?" - read the standard. – too honest for this site Mar 01 '16 at 19:46
  • @R_Kapp Thanks for pointing that out. I switched them in my comment. – callyalater Mar 01 '16 at 19:47
  • @callyalater Yeah, you are correct. That is what I was trying to ask. Thanks. – itsme.cvk Mar 01 '16 at 19:58
  • @Amit I have compiled the same in gcc and turboc. A() is not allowed to be called from B() without requiring the function prototypes at the beginning of the code in these compilers. – itsme.cvk Mar 01 '16 at 20:00
  • @itsme.cvk: "`A()` is not allowed to be called from `B()`" is a different statement from "`A()` cannot call `B()`". The first statement (and the one you've made in the comments here) is correct. The second statement (the one you have in the question) is incorrect. `A` *can* call `B`. – R_Kapp Mar 01 '16 at 20:05
  • @R_Kapp Thanks. I have corrected it. :) So, is B() allowed to call A() without using the function prototype at the beginning of the program ? – itsme.cvk Mar 01 '16 at 20:09
  • " is B() allowed to call A() without using the function prototype at the beginning of the program ?" --> Yes. Will it work? --> doubtful. C gives the coder lots of rope, enough to hurt oneself. – chux - Reinstate Monica Mar 01 '16 at 20:11
  • 1
    Both functions can call each other in all versions of Standard C. If you get a compilation error then you probably made a mistake in your code. To get help with that, post the *exact* code that is giving the error. – M.M Mar 01 '16 at 20:11
  • 2
    [Here](http://goo.gl/TmNpWu) is a sample where `B()` calls `A()` and it works. GCC gives a warning about an implicit function declaration, but it works. – callyalater Mar 01 '16 at 20:15
  • @callyalater Thanks a lot. The concept it pretty clear for me now. When I ran the same code in www.codechef.com (gcc compiler) it throws an error. – itsme.cvk Mar 01 '16 at 20:41

1 Answers1

4

(Posting this answer as there are many misconceptions in the main comments):

  • In all versions of Standard C, A can call B, and B can call A
  • A prototype is not required in any version of Standard C. (But it is a good idea to use one anyway as they help the compiler to diagnose errors).
  • In ISO C99 and ISO C11, a function declaration must be visible of the function being called.
  • In ISO C90, it is possible to call a function without a visible declaration. This call runs correctly if all of the following conditions are met (otherwise the behaviour is undefined):
    • The function definition returns int (or omits the return type)
    • The function definition is not variadic
    • The ordered list of types of the arguments, after the default argument promotions are applied, matches exactly the ordered list of types of the parameters to the function definition (the parameter types are not promoted).

For example, in all versions of Standard C, the ... in the OP code inside B() may be replaced with:

void A();
A(w, i);

making a correct program. In ISO C90, the ... may be replaced with simply:

A(w, i);

The standards makes this legal in order to avoid breaking existing code which was written before prototypes were invented. It would be embarrassing if the code in K&R1 stopped working in Standard C.

I repeat that it is not a good idea to do this on purpose if you are writing new code; it's better to put a prototype, and the best position for the prototype is outside of the function.


You can download drafts of the ISO C11 standard, and the ISO C99+TC3 standard here. AFAIK there is no free and legal copy of the C90 or original C99 text. The cheapest legal way to get the C90 text is to buy the book The Annotated C Standard. This is cheaper than buying it from ISO, although it is said that the price difference represents the added value of the annotations.

There are many second-hand sources of information about Standard C, e.g. questions on this site which are tagged .

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • After checking the C11 Standard, I found that it does not explicitly state that this behavior is permitted, but it also doesn't say that it is prohibited. The only place that kinda related to this issue was Section 6.2.2 (Linkages of Identifiers) Paragraph 4, footnote 31. This seems to imply that this is a function of the linker, not the compiler, and will be resolved at runtime. – callyalater Mar 01 '16 at 20:42
  • @callyalater which behaviour are you referring to specifically? – M.M Mar 01 '16 at 20:56
  • Implicit function declaration and calling a function before being fully qualified and defined. I see stuff regarding function prototypes, but it doesn't say anything regarding calling a function that has an implicit function declaration before it has been properly defined. – callyalater Mar 01 '16 at 21:00
  • @callyalater "implicit function declaration" only existed up to C90, so you won't find anything about it in C11. Attempting to call an undeclared function since C99 fails under the same provision that `x = 5;` fails when `x` is not declared, i.e. identifiers must be declared before use unless specifically noted otherwise. C11 section 6.5.2.2 describes the rules surrounding function calls with and without a prototype. – M.M Mar 01 '16 at 21:06
  • @MM Thank you for the section reference! `x = 5;` would cause a compilation error, while using a function that is not declared yet only cause a warning and is resolved at link time. Why the difference? I'm really curious. – callyalater Mar 01 '16 at 21:12
  • 1
    @callyalater using a function that is not declared is also an error, since C99. Compilers often allow extensions beyond what the C Standard requires (they are allowed to do so, so long as they print a message and they don't break the behaviour of any correct program). You could try invoking your compiler in conforming mode (e.g. for gcc , `-std=c11 -pedantic`) – M.M Mar 01 '16 at 21:17