Why Do Functions Need to Be Declared Before They Are Used

Why do functions need to be declared before they are used?

How do you propose to resolve undeclared identifiers that are defined in a different translation unit?

C++ has no module concept, but has separate translation as an inheritance from C. A C++ compiler will compile each translation unit by itself, not knowing anything about other translation units at all. (Except that export broke this, which is probably why it, sadly, never took off.)

Header files, which is where you usually put declarations of identifiers which are defined in other translation units, actually are just a very clumsy way of slipping the same declarations into different translation units. They will not make the compiler aware of there being other translation units with identifiers being defined in them.

Edit re your additional examples:

With all the textual inclusion instead of a proper module concept, compilation already takes agonizingly long for C++, so requiring another compilation pass (where compilation already is split into several passes, not all of which can be optimized and merged, IIRC) would worsen an already bad problem. And changing this would probably alter overload resolution in some scenarios and thus break existing code.

Note that C++ does require an additional pass for parsing class definitions, since member functions defined inline in the class definition are parsed as if they were defined right behind the class definition. However, this was decided when C with Classes was thought up, so there was no existing code base to break.

Why do we need to declare functions before using them in C?

Actually, it is not required that a function be declared before use in C. If it encounters an attempt to call a function, the compiler will assume a variable argument list and that the function returns int.

The reason modern compilers give warnings on an attempt to call a function before seeing a declaration is that a declaration allows the compiler to check if arguments are of the expected type. Given a declaration, the compiler can issue warnings or errors if an argument does not match the specification in the function declaration. This catches a significant percentage of errors by the programmer.

As to why the compiler doesn't look ahead for a definition, there are a few contributing factors. Firstly, there is the separate compilation model of C - there is no guarantee that there will be a function definition to be found within the current compilation unit (i.e. source file). Second, it allows the compiler to work in one pass, which increases performance. Third, it does encourage the programmer to actually declare functions (e.g. in header files) which allows for reuse with a separate compilation model. Fourth, it increases the chances of a compiler actually being able to function on machines with limited memory resources.

Why can I use a function before it's defined in JavaScript?

The function declaration is magic and causes its identifier to be bound before anything in its code-block* is executed.

This differs from an assignment with a function expression, which is evaluated in normal top-down order.

If you changed the example to say:

var internalFoo = function() { return true; };

it would stop working.

The function declaration is syntactically quite separate from the function expression, even though they look almost identical and can be ambiguous in some cases.

This is documented in the ECMAScript standard, section 10.1.3. Unfortunately ECMA-262 is not a very readable document even by standards-standards!

*: the containing function, block, module or script.

Why do some functions need 'function' declared before the function name?

The first function declaration would only work in the objects and classes. If you want to declare a function outside of an object or a class then you have to use either function keyword or an arrow function.

Do class functions/variables have to be declared before being used?

Good question; I've relied on that feature for years without thinking about it. I looked through several C++ books to find an answer, including Stroustrup's The C++ Programming Language and The Annotated C++ Reference Manual, but none acknowledge or explain the difference. But, I think I can reason through it.

The reason, I believe, that your example works is that the bodies of your test and printout aren't truly where they appear in your file. The code

class MyClass {
void someFun() {
x = 5;
}
int x;
};

...which appears to violate the rule of having to declare variables before you use them, is actually equivalent to:

class MyClass {
void someFun();
int x;
};

void MyClass::someFun() {
x = 5;
}

Once we rewrite it like that, it becomes apparent that the stuff inside your MyClass definition is actually a list of declarations. And those can be in any order. You're not relying on x until after it's been declared. I know this to be true because if you were to rewrite the example like so,

void MyClass::someFun() {
x = 5;
}

class MyClass {
void someFun();
int x;
};

...it would no longer compile! So the class definition comes first (with its complete list of members), and then your methods can use any member without regard for the order in which they're declared in the class.

The last piece of the puzzle is that C++ prohibits declaring any class member outside of the class definition, so once the compiler processes your class definition, it knows the full list of class members. This is stated on p.170 of Stroustrup's The Annotated C++ Reference Manual: "The member list defines the full set of members of the class. No member can be added elsewhere."

Thanks for making me investigate this; I learned something new today. :)



Related Topics



Leave a reply



Submit