0

C++ Program:

#include<iostream>

int main(){
    sayHello();
}

void sayHello(){
    std::cout << "Hello\n";
}

Output:

main.cpp: In function 'int main()':
main.cpp:4:5: error: 'sayHello' was not declared in this scope
     sayHello();
     ^~~~~~~~

Java Program:

public class Main
{
    public static void main(String[] args) {
        sayHello();
    }
    
    public static void sayHello(){
        System.out.println("Hello");
    }
}

Output:

Hello

Is it just because Java provides support to resolve any dependencies among functions during compilation but C++ does not. If yes, Is there a specific reason that C++ did not provide this feature?

  • 2
    https://stackoverflow.com/questions/4757705/why-do-functions-need-to-be-declared-before-they-are-used – shmosel Feb 25 '22 at 08:18
  • 2
    Java doesn't have "free" functions, so that's a bad comparison. Put your C++ code inside a class `Main`, and change `main` to `int main() { Main m; m.main(); }`. Abra cadabra, difference disappeared. – molbdnilo Feb 25 '22 at 08:22
  • @molbdnilo: You'd still need to define `Main` before `int main` though. – MSalters Feb 25 '22 at 08:29
  • @MSalters Yes, but it's less apples to oranges and more Cox's Orange Pippins to Granny Smiths. – molbdnilo Feb 25 '22 at 08:31
  • 1
    C++ is not Java, and Java is not C++. Why does COBOL use English words, but C++ doesn't? Why does FORTRAN have computed goto's and C++ doesn't? Why does C++ have vector, but `C` doesn't. We can go on and on... Just accept that the languages are different. And BTW, in `C`, you *can* call functions without declaring them (at least K&R C). So are we going to compare `C` to Java? – PaulMcKenzie Feb 25 '22 at 09:19
  • The short explanation is that Java and C++ are different languages, designed for different purposes. C++ has a different compilation model, that essentially requires everything to be declared before its use in any compilation unit (aka source file). Compiled Java is run by a JVM (Java Virtual Machine) which does the work of dynamically finding and loading the class who's `Main()` function is called at run time and resolving calls to functions in other classes. The closest analog of the JVM in C++ is an abstract machine, that doesn't support anything akin to the JVM's loading of classes. – Peter Feb 25 '22 at 09:19

2 Answers2

2

This is because code becomes available only after its declaration. In your C++ example, you could declare sayHello() before defining main() like this:

#include <iostream>

void sayHello();

int main() {
    sayHello();
}

void sayHello() {
    std::cout << "Hello\n";
}

What's different about Java is that every file contains a class. When a class is defined, first all of the class members are declared, and only then their definition is considered. So in your Java example, first class Main is defined with methods main(String[]) and sayHello(), and only then it's defined that the main method calls sayHello that is already declared. You can replicate this behaviour in C++ by creating a class like in Java:

#include <iostream>

class Main {
public:
    static void main() {
        sayHello();
    }
    static void sayHello() {
        std::cout << "Hello\n";
    }
};

int main()
{
    Main::main();
}
FlyMaster
  • 36
  • 5
-2

the difference in the code above is that in C++ you have two methods and main method is run before the sayHello() method due to which compiler does not know that sayHello exists.

Whereas in Java you have a class which contains those methods. So when you run the code the class is created along which all the methods are known to the compiler, then when main method is run it is able to execute sayHello() method.

I hope it clarifies your question.

Bobo
  • 7
  • 2
  • This is wrong. C++ is a compiled language. Everything is known to the compiler before the executable is created, and main can only run after the executable is created. – MSalters Feb 25 '22 at 08:28
  • And note that even in C++ member function definitions logically follow member declarations. For example: struct foo { int (foo::*ptr)() = &foo::y; int x() { return y(); } int y() { return 5; } }; Even though "y" hasn't been seen during an in-order scan (as a human would do) it is still in scope for both the initialization of ptr and inside the body of x. – SoronelHaetir Feb 25 '22 at 08:30