tags:

views:

390

answers:

7

In C its optional. In C++ one "MUST" declare a function before its used/defined. Why is it so? Whats the need? We don't do that in C# or Java.

Funny thing is while we are defining a function. The definition itself has a declaration even then, we need to declare. God knows why?

+20  A: 

Funny that you mention that, just this week Eric Lippert wrote a blog post related to your question :

http://blogs.msdn.com/ericlippert/archive/2010/02/04/how-many-passes.aspx

Basically, this is related to how the compiler works. The C# and Java compilers make several passes. If they encounter a call to a method that is not yet known, that's not an error, because the definition might be found later and the call will be resolved at the next pass. Note that my explanation is overly simplistic, I suggest you read Eric Lippert's post for a more complete answer...

Thomas Levesque
+7  A: 

Java and C# specify both the language and the binary object file format, and they are multi-pass compilers.

As a result, they are able to peek at later definitions or those that were compiled separately.

C doesn't work this way for several reasons:

  • Without using managed code it is a lot harder to define a machine-independent object format with type information

  • C deliberately allows bypassing the type mechanisms

  • When originally defined, there generally wasn't enough memory to run sophisticated compilers, nor were there prototypes to read anyway

  • C programs must be arbitrarily large with system-specific library and search path mechanisms. All of this gets in the way of defining an object-module-based type system

  • Part of the C portability and interoperation basis is the "input language only" nature of the specification

  • Until recently, even the limited one-pass nature of C was still barely practical for large programs. Something like Java or C# would have been out of the question: you could take a vacation and your make(1) would still not be done

DigitalRoss
The last point actually is a weakness of `make(1)`, not so much C. It's quite generic and powerful, but at a very large price: `make` doesn't understand a thing of what it's doing. A more specialized tool can be much, much more effective in building C by understanding the basics of C. E.g. `make` just doesn't grok headers.
MSalters
+4  A: 

Basically, it's down to how you write the compiler for the language. In C++, the decision has been to make a one pass compilation possible. To do that, you (or rather the compiler) need to be able to first read the declaration of all classes, methods and the like and then read the implementation (or in C++ terms, the definition). In Java and C#, the compiler first reads through all the code generating what corresponds to what the C++ compiler generates when reading the header files. The C#/Java compiler then reads the implementation (aka definition). So, in C++, the developer is asked to write the declaration whereas in C#, the compiler runs through the code multiple times doing the declaration work for the developer.

As an aside, other languages used to ask you to write the functions in the order you needed them (if function B uses function A, you have to define A first). Most of those languages had constructs to allow you to get around this. In (Turbo) Pascal, the solution was, in a kind, the same as in C++.

Rune FS
A: 

The not requiring a prototype before using the function caused horrible problems. It would allow you do such bad things as:

malloc("foo");

if the compiler does not have a declaration, it doesn't know that this is a bad way to call it.

As for requiring a prototype even when you see the definition before using it, that is not a requirement of the C++ spec. gcc has an option (-Wmissing-prototypes) that enables that behavior but you can turn it off.

R Samuel Klatchko
Not requiring a prototype does not result in you being able to make calls like myFunction("foo") where myFunction is undefined. It's the combination of a single pass compiler (e.g. c++ compilers) and no prototype. Java/C# compilers would still complain about the missing function eventhough there's no prototyping in those languages
Rune FS
@RuneFS - yes, if the function is undefined, you can't call it (the link will eventually fail). But if the function is defined and you don't have a declaration, you can do bad things like call a function with the wrong parameters. As the questioner notes, it's optional in C - I am pointing out why that's bad.
R Samuel Klatchko
And im pointing out that it's not the lack of an explicit declaration that causes that problem but how the compiler works. All the needed information is available to the compiler it simply opts to ignore it
Rune FS
@RuneFS - are we even discussing the same thing (I'm comparing the optional of C to the mandatory of C++). If we are just talking C and C++, where is this information that is available to the C or C++ compiler that it is ignoring?
R Samuel Klatchko
The question is why declaration are needed and the short answer to that is they are _not_. You Can build a compiler with out (Java/C#) but that however is not saying that the C(++) compiler dont need Them but then again the question is asking why you have to in C when you dont have to in C#. And your answer is wrong in the context of the comparison but correct in explaining what the C compiler uses them for
Rune FS
Still your answer doesn't make sense. The C compiler could just put in a call to the (name-mangled) function `malloc__CharConstPtr`. The linker would then catch this error. Deosn't require a multi-pass solution, todays 2-pass model is sufficient.
MSalters
@RuneFS - there are two questions. 1 - why are C++ declarations required while C declarations are optional. 2 - why does C/C++ need declarations at all. I've **only** answered the first question and have not answered the second question. I've never implied that declarations are the only way to solve the problem - my point is that if the language does use declarations as the solution, required is better then optional.
R Samuel Klatchko
A: 

In C++ one "MUST" declare a function before its used/defined. Why is it so? Whats the need? We don't do that in C# or Java.

I would like to say, that is not true. Yes, in C++ you have to define a function signature (prototype), before referring to it. But you may leave the implementation for a later time.

In Java that does not work: you cannot call the method of some class without having that class compiled (note: together with implementation) and available in javac classpath. So, Java is more strict in this sense.

dma_k
I didn't -1 you because I think -2 is enough. However, have you heard about interfaces? In OOP they are as close to function prototypes you can get.
Fredrik
The part about java is simply not true. The Java spec says: "Types declared in different compilation units can depend on each other, circularly. A Java compiler must arrange to compile all such types at the same time" (7.3)
nikie
The part about C++ isn't true either. The guy in the question is right.
Johannes Schaub - litb
+1  A: 

C++ vs. Java/C# - Single-pass compiler (C++) vs. multi-pass compiler (Java & C#). Multiple passes allow Java and C# compilers to peek at future types and functions prototypes.

C++ vs. C - The C feature to have default declaration is basically a bug, fixed in C++. It causes problems, and it is an enabled warning for gcc. In C++ the arguments form part of the function exported name (name-mangling), so must be known before the correct function can be called.

Douglas Leeder
A: 

Note that in C++, when you are writing functions inline the class declaration, as follows, you can do it like in C# or Java:

struct Foo {
    void foo () { bar(); }
    void bar () {}
};
phresnel