Hubbry Logo
Entry pointEntry pointMain
Open search
Entry point
Community hub
Entry point
logo
7 pages, 0 posts
0 subscribers
Be the first to start a discussion here.
Be the first to start a discussion here.
Entry point
Entry point
from Wikipedia
Example of the main function, in C#.
How the Main() might look in C# source code. Different parts are labeled for reference.

In computer programming, an entry point is the place in a program where the execution of a program begins, and where the program has access to command line arguments.[failed verification][1]

To start a program's execution, the loader or operating system passes control to its entry point. (During booting, the operating system itself is the program). This marks the transition from load time (and dynamic link time, if present) to run time.

For some operating systems and programming languages, the entry point is in a runtime library, a set of support functions for the language. The library code initializes the program and then passes control to the program proper. In other cases, the program may initialize the runtime library itself.[2]

In simple systems, execution begins at the first statement, which is common in interpreted languages, simple executable formats, and boot loaders. In other cases, the entry point is at some other known memory address which can be an absolute address or relative address (offset).

Alternatively, execution of a program can begin at a named point, either with a conventional name defined by the programming language or operating system or at a caller-specified name. In many C-family languages, this is a function called main; as a result, the entry point is often known as the main function.[3]

In JVM languages, such as Java, the entry point is a static method called main; in CLI languages such as C# the entry point is a static method named Main.[4]

Usage

[edit]

Entry points apply both to source code and to executable files. However, in day-to-day software development, programmers specify the entry points only in source code, which makes them much better known. Entry points in executable files depend on the application binary interface (ABI) of the actual operating system, and are generated by the compiler or linker (if not fixed by the ABI). Other linked object files may also have entry points, which are used later by the linker when generating entry points of an executable file.

Entry points are capable of passing on command arguments, variables, or other information as a local variable used by the Main() method. This way, specific options may be set upon execution of the program, and then interpreted by the program. Many programs use this as an alternative way to configure different settings, or perform a set variety of actions using a single program.

Contemporary

[edit]

In most of today's popular programming languages and operating systems, a computer program usually only has a single entry point.

In C, C++, D, Zig, Rust and Kotlin programs this is a function named main; in Java it is a static method named main (although the class must be specified at the invocation time), and in C# it is a static method named Main.[5][6]

In many major operating systems, the standard executable format has a single entry point. In the Executable and Linkable Format (ELF), used in Unix and Unix-like systems such as Linux, the entry point is specified in the e_entry field of the ELF header. In the GNU Compiler Collection (gcc), the entry point used by the linker is the _start symbol. Similarly, in the Portable Executable format, used in Microsoft Windows, the entry point is specified by the AddressOfEntryPoint field, which is inherited from COFF. In COM files, the entry point is at the fixed offset of 0100h.

One exception to the single-entry-point paradigm is Android. Android applications do not have a single entry point – there is no special main function. Instead, they have essential components (activities and services) which the system can load and run as needed.[7]

An occasionally used technique is the fat binary, which consists of several executables for different targets packaged in a single file. Most commonly, this is implemented by a single overall entry point, which is compatible with all targets and branches to the target-specific entry point. Alternative techniques include storing separate executables in separate forks, each with its own entry point, which is then selected by the operating system.

Historical

[edit]

Historically, and in some contemporary legacy systems, such as VMS and OS/400, computer programs have a multitude of entry points, each corresponding to the different functionalities of the program. The usual way to denote entry points, as used system-wide in VMS and in PL/I and MACRO programs, is to append them at the end of the name of the executable image, delimited by a dollar sign ($), e.g. directory.exe$make.

The Apple I computer also used this to some degree. For example, an alternative entry point in Apple I's BASIC would keep the BASIC program useful when the reset button was accidentally pushed.[clarification needed]

Exit point

[edit]

In general, programs can exit at any time by returning to the operating system or crashing. Programs in interpreted languages return control to the interpreter, but programs in compiled languages must return to the operating system, otherwise the processor will simply continue executing beyond the end of the program, resulting in undefined behavior.

Usually, there is not a single exit point specified in a program. However, in other cases runtimes ensure that programs always terminate in a structured way via a single exit point, which is guaranteed unless the runtime itself crashes; this allows cleanup code to be run, such as atexit handlers. This can be done by either requiring that programs terminate by returning from the main function, by calling a specific exit function, or by the runtime catching exceptions or operating system signals.

Programming languages

[edit]

In many programming languages, the main function is where a program starts its execution. It enables high-level organization of the program's functionality, and typically has access to the command arguments given to the program when it was executed.

The main function is generally the first programmer-written function that runs when a program starts, and is invoked directly from the system-specific initialization contained in the runtime environment (crt0 or equivalent). However, some languages can execute user-written functions before main runs, such as the constructors of C++ global objects.

In other languages, notably many interpreted languages, execution begins at the first statement in the program.

A non-exhaustive list of programming languages follows, describing their way of defining the main entry point:

APL

[edit]

In APL, when a workspace is loaded, the contents of "quad LX" (latent expression) variable is interpreted as an APL expression and executed.

C and C++

[edit]

In C and C++, the function prototype of the main function must be equivalent to one of the following:

int main();
int main(void);
int main(int argc, char* argv[]);
int main(int argc, char** argv);

The main function is the entry point for application programs written in ISO-standard C or C++. Low-level system programming (such as for a bare-metal embedded system) might specify a different entry point (for example via a reset interrupt vector) using functionality not defined by the language standard.

If using trailing return types, C++ also supports the following signatures of main:

auto main() -> int;
auto main(int argc, char* argv[]) -> int;

The parameters argc, argument count, and argv, argument vector,[citation needed] respectively give the number and values of the program's command-line arguments. The names of argc and argv may be any valid identifier, but it is common convention to use these names. Other platform-dependent formats are also allowed by the C and C++ standards, except that in C++ the return type must always be int;[8] for example, Unix (though not POSIX.1) and Windows have a third argument giving the program's environment, otherwise accessible through getenv in stdlib.h:

int main(int argc, char* argv[], char* envp[]);

Darwin-based operating systems, such as macOS, have a fourth parameter containing arbitrary OS-supplied information, such as the path to the executing binary:[9]

int main(int argc, char* argv[], char* envp[], char* apple[]);

The value returned from the main function becomes the exit status of the process, though the C standard only ascribes specific meaning to two values: EXIT_SUCCESS (traditionally 0) and EXIT_FAILURE. The meaning of other possible return values is implementation-defined. In case a return value is not defined by the programmer, an implicit return 0; at the end of the main() function is inserted by the compiler; this behavior is required by the C++ standard.

It is guaranteed that argc is non-negative and that argv[argc] is a null pointer. By convention, the command-line arguments specified by argc and argv include the name of the program as the first element if argc is greater than 0; if a user types a command of "rm file", the shell will initialise the rm process with argc = 2 and argv = {"rm", "file", NULL}. As argv[0] is the name that processes appear under in ps, top etc., some programs, such as daemons or those running within an interpreter or virtual machine (where argv[0] would be the name of the host executable), may choose to alter their argv to give a more descriptive argv[0], usually by means of the exec system call.

On GCC and Clang, it is possible to call main() (or potentially even select a different function as the entry point) by passing the compiler flag –nostartfiles and then defining the function _start(). Arguments from command line to main() can be retrieved using inline assembly.

#include <stdio.h>
#include <stdlib.h>

void _start() {
    int exitCode = altMain();
    exit(exitCode);
}

int altMain() {
    printf("No main() function in this program.");
    return 0;
}

The main() function is special; normally every C and C++ program must define it exactly once.

If declared, main() must be declared as if it has external linkage; it cannot be declared static or inline.

In C++, main() must be in the global namespace (i.e. ::main), and cannot be overloaded. In C++ (unlike C) main() cannot be called recursively and cannot have its address taken. If main() is not defined in the global namespace (for example if it is only defined as a member function of a class), the compiler will not detect it. The name main is not otherwise reserved, and may be used for member functions, classes, enumerations, or non-member functions in other namespaces.

import std;

using std::string;
using std::vector;

class Main {
public:
    static void main(const vector<string>& args) {
        std::println("Java-style main() function");
    }
};

int main(int argc, char* argv[]) {
    vector<string> args(argv, argv + argc);
    Main::main(args);
    return 0;
}

C#

[edit]

When executing a program written in C#, the CLR searches for a static method marked with the .entrypoint IL directive, which takes either no arguments, or a single argument of type string[], and has a return type of void or int, and executes it.[10]

static void Main();
static void Main(string[] args);
static int Main();
static int Main(string[] args);

Command-line arguments are passed in args, similar to how it is done in Java. For versions of Main() returning an integer, similar to both C and C++, it is passed back to the environment as the exit status of the process.

Since C#7.1 there are four more possible signatures of the entry point, which allow asynchronous execution in the Main() Method.[11]

static async Task Main()
static async Task<int> Main()
static async Task Main(string[] args)
static async Task<int> Main(string[] args)

The Task and Task<int> types are the asynchronous equivalents of void and int. async is required to allow the use of asynchrony (the await keyword) inside the method.

Clean

[edit]

Clean is a functional programming language based on graph rewriting. The initial node is named Start and is of type *World -> *World if it changes the world or some fixed type if the program only prints the result after reducing Start.

Start :: *World -> *World
Start world = startIO ...

Or even simpler

Start :: String
Start = "Hello, world!"

One tells the compiler which option to use to generate the executable file.

Common Lisp

[edit]

ANSI Common Lisp does not define a main function; instead, the code is read and evaluated from top to bottom in a source file. However, the following code will emulate a main function.

(defun hello-main ()
  (format t "Hello World!~%"))

(hello-main)

D

[edit]

In D, the function prototype of the main function looks like one of the following:

void main();
void main(string[] args);
int main();
int main(string[] args);

Command-line arguments are passed in args, similar to how it is done in C# or Java. For versions of main() returning an integer, similar to both C and C++, it is passed back to the environment as the exit status of the process.

Dart

[edit]

Dart is a general-purpose programming language that is often used for building web and mobile applications. Like many other programming languages, Dart has an entry point that serves as the starting point for a Dart program. The entry point is the first function that is executed when a program runs. In Dart, the entry point is typically a function named main . When a Dart program is run, the Dart runtime looks for a function named main and executes it. Any Dart code that is intended to be executed when the program starts should be included in the main function. Here is an example of a simple main function in Dart:

void main() {
    print("Hello, world!");
}

In this example, the main function simply prints the text Hello, world! to the console when the program is run. This code will be executed automatically when the Dart program is run.

It is important to note that while the main function is the default entry point for a Dart program, it is possible to specify a different entry point if needed. This can be done using the @pragma("vm:entry-point") annotation in Dart. However, in most cases, the main function is the entry point that should be used for Dart programs.

FORTRAN

[edit]

FORTRAN does not have a main subroutine or function. Instead a PROGRAM statement as the first line can be used to specify that a program unit is a main program, as shown below. The PROGRAM statement cannot be used for recursive calls.[12]

      PROGRAM HELLO
      PRINT *, "Cint!"
      END PROGRAM HELLO

Some versions of Fortran, such as those on the IBM System/360 and successor mainframes, do not support the PROGRAM statement. Many compilers from other software manufacturers will allow a fortran program to be compiled without a PROGRAM statement. In these cases, whatever module that has any non-comment statement where no SUBROUTINE, FUNCTION or BLOCK DATA statement occurs, is considered to be the Main program.

GNAT

[edit]

Using GNAT, the programmer is not required to write a function named main; a source file containing a single subprogram can be compiled to an executable. The binder will however create a package ada_main, which will contain and export a C-style main function.

Go

[edit]

In Go programming language, program execution starts with the main function of the package main

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

There is no way to access arguments or a return code outside of the standard library in Go. These can be accessed via os.Args and os.Exit respectively, both of which are included in the "os" package.

Haskell

[edit]

A Haskell program must contain a name main bound to a value of type IO t, for some type t;[13] which is usually IO (). IO is a monad, which organizes side-effects in terms of purely functional code.[14] The main value represents the side-effects-ful computation done by the program. The result of the computation represented by main is discarded; that is why main usually has type IO (), which indicates that the type of the result of the computation is (), the unit type, which contains no information.

main :: IO ()
main = putStrLn "Hello, World!"

Command line arguments are not given to main; they must be fetched using another IO action, such as System.Environment.getArgs.

Java

[edit]

Java programs start executing at the main method of a class,[15][16][17][18] which has one of the following method headings:

// named class-based
public static void main();
public static void main(String[] args);
public static void main(String... args);
public static void main(String args[]);

// unnamed class-based
void main();
void main(String[] args);
void main(String... args);
void main(String args[]);

Command-line arguments are passed in args. As in C and C++, the name "main()" is special. Java's main methods do not return a value directly, but one can be passed by using the System.exit() method.

Unlike C, the name of the program is not included in args, because it is the name of the class that contains the main method, so it is already known. Also unlike C, the number of arguments need not be included, since arrays in Java have a field that keeps track of how many elements there are.

The main function must be included within a class. This is because in Java everything has to be contained within a class. For instance, a hello world program in Java may look like:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}

To run this program, one must call java HelloWorld in the directory where the compiled class file HelloWorld.class) exists. Alternatively, executable JAR files use a manifest file to specify the entry point in a manner that is filesystem-independent from the user's perspective.

Since Java 25, it is possible to create a "compact source file" which implicitly declares a final class in the unnamed package. This class extends java.lang.Object and does not implement any interfaces, has only a default constructor, and has the fields and methods declared in the compact source file.[19] Furthermore, Java 25 moves the class java.io.IO to the package java.lang (thus implicitly importing it into all source files), based on System.out and System.in rather than java.io.Console. This allows a simplified Hello World program, perhaps more similar to C and C++ where main resides in the global namespace:

void main() {
    IO.println("Hello, world!");
}

Julia

[edit]

In Julia the entry point (at least for scripts, see below for compiled programs) is the program file you itself you run, i.e. from the very first line so you can simply do (or start with):

println("Hello, world! Called from $PROGRAM_FILE with following arguments:"); for x in ARGS; println(x); end

Since Julia version 1.11 there's also the possibility of defining a main function that will be called as an entry point, and it can e.g. look like this if using the associated @main macro:

(@main)(ARGS) = println("Hello World! Called from main.")

For compatibility with prior Julia versions, such as Julia 1.10 (LTS), the above line can be made to work with one extra line from the documentation, and using this way can help since the new "feature is intended to aid in the unification of compiled and interactive workflows."[20] Other ways documented elsewhere[21] are no longer needed.

The former println above showing the older way for an entry point without defining a main function is still perfectly fine for scripts (and ARGS is available in both cases, there directly from the a global variable; and PROGRAM_FILE in either case). Note if you do both, scripts will still run the first line as usual, and from there onward so this would also call main and print twice. But neither is necessarily the first code run unless you invoke Julia with --startup-file=no since the default Julia startup file is run before anything else (it's empty after install, but can easily be forgotten e.g. when benchmarking, if you've added to it).

The exit status is 0 by default (on success, throwing changes that), and exit(my_exit_code) exits the program with a non-default one.

[edit]

In FMSLogo, the procedures when loaded do not execute. To make them execute, it is necessary to use this code:

to procname
 ...                 ; Startup commands (such as print [Welcome])
end
make "startup [procname]

The variable startup is used for the startup list of actions, but the convention is that this calls a procedure that runs the actions. That procedure may be of any name.

OCaml

[edit]

OCaml has no main function. Programs are evaluated from top to bottom.

Command-line arguments are available in an array named Sys.argv and the exit status is 0 by default.

Example:

print_endline "Hello World"

Pascal

[edit]

In Pascal, the main procedure is the only unnamed block in the program. Because Pascal programs define procedures and functions in a more rigorous bottom-up order than C, C++ or Java programs, the main procedure is usually the last block in the program. Pascal does not have a special meaning for the name "main" or any similar name.

program Hello(Output);
begin
  writeln('Hello, world!');
end.

Command-line arguments are counted in ParamCount and accessible as strings by ParamStr(n), with n between 0 and ParamCount.

Versions of Pascal that support units or modules may also contain an unnamed block in each, which is used to initialize the module. These blocks are executed before the main program entry point is called.

Perl

[edit]

In Perl, there is no main function. Statements are executed from top to bottom, although statements in a BEGIN block are executed before normal statements.

Command-line arguments are available in the special array @ARGV. Unlike C, @ARGV does not contain the name of the program, which is $0.

PHP

[edit]

PHP does not have a "main" function. Starting from the first line of a PHP script, any code not encapsulated by a function header is executed as soon as it is seen.

Pike

[edit]

In Pike syntax is similar to that of C and C++. The execution begins at main. The "argc" variable keeps the number of arguments passed to the program. The "argv" variable holds the value associated with the arguments passed to the program.

Example:

 int main(int argc, array(string) argv)

Python

[edit]

Python programs are evaluated top-to-bottom, as is usual in scripting languages: the entry point is the start of the source code. Since definitions must precede use, programs are typically structured with definitions at the top and the code to execute at the bottom (unindented), similar to code for a one-pass compiler, such as in Pascal.

Alternatively, a program can be structured with an explicit main function containing the code to be executed when a program is executed directly, but which can also be invoked by importing the program as a module and calling the function. This can be done by the following idiom, which relies on the internal variable __name__ being set to __main__ when a program is executed, but not when it is imported as a module (in which case it is instead set to the module name); there are many variants of this structure:[22][23][24]

import sys

def main(argv: List[str]) -> int:
    argc: int = len(argv) # get length of argv
    n: int = int(argv[1])
    print(n + 1)
    return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv))

In this idiom, the call to the named entry point main is explicit, and the interaction with the operating system (receiving the arguments, calling system exit) are done explicitly by library calls, which are ultimately handled by the Python runtime. This contrasts with C, where these are done implicitly by the runtime, based on convention.

QB64

[edit]

The QB64 language has no main function, the code that is not within a function, or subroutine is executed first, from top to bottom:

print "Hello World! a =";
a = getInteger(1.8d): print a
function getInteger(n as double)
    getInteger = int(n)
end function

Command line arguments (if any) can be read using the COMMAND$ function:

dim shared commandline as string
commandline = COMMAND$
'Several space-separated command line arguments can be read using COMMAND$(n)
commandline1 = COMMAND$(2)

Ruby

[edit]

In Ruby, there is no distinct main function. Instead, code written outside of any class .. end or module .. end scope is executed in the context of a special "main" object. This object can be accessed using self:

irb(main):001:0> self
=> main

It has the following properties:

irb(main):002:0> self.class
=> Object
irb(main):003:0> self.class.ancestors
=> [Object, Kernel, BasicObject]

Methods defined outside of a class or module scope are defined as private methods of the "main" object. Since the class of "main" is Object, such methods become private methods of almost every object:

irb(main):004:0> def foo
irb(main):005:1>   42
irb(main):006:1> end
=> nil
irb(main):007:0> foo
=> 42
irb(main):008:0> [].foo
NoMethodError: private method `foo' called for []:Array
	from (irb):8
	from /usr/bin/irb:12:in `<main>'
irb(main):009:0> false.foo
NoMethodError: private method `foo' called for false:FalseClass
	from (irb):9
	from /usr/bin/irb:12:in `<main>'

The number and values of command-line arguments can be determined using the ARGV constant array:

$ irb /dev/tty foo bar

tty(main):001:0> ARGV
ARGV
=> ["foo", "bar"]
tty(main):002:0> ARGV.size
ARGV.size
=> 2

The first element of ARGV, ARGV[0], contains the first command-line argument, not the name of program executed, as in C. The name of program is available using $0 or $PROGRAM_NAME.[25]

Similar to Python, one could use:

if __FILE__ == $PROGRAM_NAME
  # Put "main" code here
end

to execute some code only if its file was specified in the ruby invocation.

Rust

[edit]

In Rust, the entry point of a program is a function named main. By convention, this function is situated in a file called main.rs.

// In main.rs
fn main() {
    println!("Hello, World!");
}

Additionally, as of Rust 1.26.0, the main function may return a Result:[26]

use std::io::Error;

fn main() -> Result<(), Error> {
    println!("Hello, World!");

    Ok(())  // Return a type Result of value Ok with the content (), the unit type.
}

Rust does not have parameters in the main() function like C++ and Java or other C-style languages. Instead, it accesses command-line arguments using std::env::args(), which returns std::env::Args and can then be converted to Vec<String> using .collect().

use std::env;
use std::env::Args;
use std::io::Error;

fn main() -> Result<(), Error> {
    let args: Args = env::args(); // get the command line args
    let args_vec: Vec<String> = args.collect(); // collect args into a Vec<String>

    for arg in args_vec {
        println!("{}", arg);
    }

    Ok(())
}

Swift

[edit]

When run in an Xcode Playground,[27] Swift behaves like a scripting language, executing statements from top to bottom; top-level code is allowed.

// HelloWorld.playground

let hello = "hello"
let world = "world"

let helloWorld = hello + " " + world

print(helloWorld) // hello world

Cocoa- and Cocoa Touch-based applications written in Swift are usually initialized with the @NSApplicationMain and @UIApplicationMain attributes, respectively. Those attributes are equivalent in their purpose to the main.m file in Objective-C projects: they implicitly declare the main function that calls UIApplicationMain(_:_:_:_:)[28] which creates an instance of UIApplication.[29]

The following code is the default way to initialize a Cocoa Touch-based iOS app and declare its application delegate.

// AppDelegate.swift

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        return true
    }
    
}

Visual Basic

[edit]

In Visual Basic, when a project contains no forms, the startup object may be the Main() procedure. The Command$ function can be optionally used to access the argument portion of the command line used to launch the program:

Sub Main()
    Debug.Print "Hello World!"
    MsgBox "Arguments if any are: " & Command$
End Sub

Xojo

[edit]

In Xojo, there are two different project types, each with a different main entry point. Desktop (GUI) applications start with the App.Open event of the project's Application object. Console applications start with the App.Run event of the project's ConsoleApplication object. In both instances, the main function is automatically generated, and cannot be removed from the project.

See also

[edit]

References

[edit]
[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
In , an entry point is the specific location in a program's or a where execution formally begins when the program or module is invoked by the runtime environment. This point typically consists of a designated function or block that initializes the application, processes command-line arguments, and orchestrates subsequent operations, ensuring proper setup of resources like the and static constructors. The form of an entry point varies across programming languages and environments, reflecting their design philosophies and runtime models. In languages like C and C++, the entry point is usually the main function (or wmain for wide-character support), which the linker automatically calls after runtime initialization; for Windows GUI applications, it may instead be WinMain or wWinMain. In Java, the entry point is a class containing a public static void main(String[] args) method, which the Java Virtual Machine (JVM) invokes to start the application. For dynamically linked libraries (DLLs) in Windows, the entry point is often DllMain, called by the operating system during loading or unloading to perform initialization and cleanup tasks. Beyond executables, entry points also play a role in modular and extensible systems. In Python, while scripts execute top-level code as the entry point when run directly (often guarded by if __name__ == "__main__":), the language's system uses entry points as a mechanism for distributions to advertise discoverable components, such as console scripts or plugins, enabling dynamic integration without hard-coded dependencies. This concept underscores the entry point's importance in ensuring portability, , and reliable program startup across diverse computing platforms.

Overview

Definition and Purpose

In , an refers to the specific function, subroutine, or instruction that serves as the initial for a program's execution once it has been loaded into memory by the operating system or runtime environment. This designated starting address ensures that the processor begins processing the program's code from a predefined point rather than an arbitrary . The primary purpose of an entry point is to facilitate the orderly initialization of essential program components, including runtime libraries, global variables, stacks, and heaps, before transferring control to the main application logic. By enforcing a controlled commencement, it prevents that could arise from executing uninitialized code segments or jumping to incorrect addresses, thereby establishing a reliable for the entire program lifecycle. Key characteristics of an entry point include its unique identifiability by the linker or , often achieved through standardized (such as "main" in many high-level languages) or explicit attributes specified during compilation and linking processes. In practice, entry points can manifest as main functions in high-level languages, where they handle command-line arguments and orchestrate high-level operations, or as reset vectors in low-level assembly code, which point to the processor's initial instruction upon power-on or reset to initiate hardware and software setup.

Role in Execution Flow

The loader or runtime environment initiates program execution by transferring control to the entry point after loading the into , allocating space for , , and stack, and resolving external symbols and references. This transfer sets the to the entry point's address, marking the transition from operating system management to user-defined . From the entry point, execution proceeds through a structured that begins with runtime initialization routines, which configure essential components such as the stack for function calls and local variables, the heap for dynamic memory allocation, and global or static variables by initializing them to default values or invoking constructors in languages like C++. These routines, often implemented in startup code like _start in C environments, also process operating system-provided arguments, such as command-line parameters passed via argc and argv in the main function, enabling the program to adapt to invocation context. Once initialization completes, control branches to the core application logic, directing the sequence of operations that define the program's behavior. Error handling at the entry point focuses on early failure detection during initialization, with mechanisms like return codes from the entry function signaling issues such as shortages or invalid configurations to the operating , which interprets non-zero values as abnormal termination. If initialization fails prior to reaching user code, the loader may report errors like unresolved symbols or memory allocation issues, preventing execution altogether. In compiled environments, the entry point bridges operating system calls—such as process creation and signal handling—with user code by invoking platform-specific runtime libraries that abstract hardware details. In contrast, interpreted environments rely on the language runtime, like a Python interpreter, to load source code, compile it on-the-fly to bytecode, and start execution from the script's top-level statements or a designated main block, integrating OS interactions through the interpreter's event loop or module system without a fixed binary entry symbol.

Historical Development

Early Concepts in Computing

The concept of an entry point in originated in the 1940s with vacuum-tube based machines like the , where execution began at a fixed starting location determined by hardware configuration rather than stored instructions. In the , completed in 1945, programs were set up through patch cords and switches that defined the sequence of operations across its 40 panels, including 20 accumulators functioning as both computational units and temporary storage. The entry point was effectively the initial "line" of the program, initiated by stimulating the master programmer unit, which sequenced orders unless altered by jump instructions transferring control to the designated start of a new sequence; these jumps were specified via switches on the function units, ensuring execution commenced from a predefined hardware address without modifiable program storage. Punch-card and punched-tape systems in the late and further exemplified implicit entry points, as programs lacked a formal designation like a "main" function and instead started sequentially from the physical beginning of the input medium. In punch-card setups, such as those used with early tabulating machines adapted for computing, the program deck began reading from column 1 of the first card, with conventions limiting to columns 1-72 to align with the 80-column format; the loader would interpret this initial card as the program's origin, loading instructions into memory starting from a fixed location without explicit address specification. Similarly, punched-paper tape systems, common in machines like the (operational from 1944), commenced execution from the tape leader or first punched block, where the absence of headers meant the entry point was inherently the onset of readable data, relying on the reader's hardware to initiate sequential processing. At the assembly level, early assemblers introduced directives to explicitly set starting addresses, marking a transition toward more structured program organization. For instance, the ORG (origin) directive in assemblers for machines like the from 1952 allowed programmers to specify the memory location for the first instruction, such as ORG 1000 to begin assembly at address 1000; this facilitated absolute addressing in symbolic code translated to machine instructions, preventing overlaps and aligning with hardware memory maps in vacuum-tube systems. A key milestone came with stored-program computers in the , exemplified by the , operational in 1949, where entry points were managed via loader-specified jumps following program input. David Wheeler's initial orders, a 32-word bootstrap routine hand-set into using uniselectors, read the user's paper tape program into consecutive locations starting at word 33; upon completion, it executed an unconditional jump to the entry point at the loaded program's start, establishing the first practical mechanism for dynamic program initiation in a stored-program architecture. This approach, detailed in the 1951 book by Wilkes, Wheeler, and , enabled reliable transfer of control without manual reconfiguration, influencing subsequent systems.

Evolution Through Decades

In the , entry points emerged as a key abstraction in operating systems like , where they were implemented as named symbols within segments that could be linked by loaders to facilitate modular program execution. , developed starting in 1965 by MIT, , and , allowed segments—units of code or data—to have multiple entry points, enabling alternate starting locations for execution and supporting dynamic linking during loading. This approach marked a shift from rigid, hardware-bound starts to software-defined entry symbols, improving program modularity in multi-user environments. During the and 1980s, entry points standardized in systems, with the C runtime using _start as the initial entry symbol before invoking main(), which received argc and argv parameters for command-line arguments. , originating in the early at , established this model where the loader passed argument counts and vectors via the stack, influencing portable program design across systems. The rise of structured programming in this era, championed by Edsger Dijkstra's 1972 work, emphasized single-entry/single-exit modules, reinforcing clear entry points to reduce complexity in procedural code. A pivotal event was the 1989 standard (X3.159-1989), which formalized main() as the program's primary entry function with signatures like int main(int argc, char *argv[]), ensuring consistent behavior across implementations. This standardization built on earlier high-level languages like , which introduced the MAIN program block in 1957 as the designated entry point for execution. In the , the advent of graphical user interfaces and modular architectures further evolved entry points, notably in the Windows (PE) format introduced with in 1993, where the entry point was specified as a Relative Virtual Address (RVA) in the optional header for efficient loading. This RVA-based design supported dynamic relocation and dependency resolution, impacting executable portability on x86 systems. Concurrently, early efforts, such as IBM's OS/2 (MVDM) introduced in OS/2 2.0 pre-release in 1991 and VMware's x86 hypervisor prototype in 1998, began abstracting entry points within virtual machines, allowing isolated execution starts without direct hardware access. These developments accommodated GUI-driven launches and modular DLLs, prioritizing flexible entry handling in distributed environments. By the early 2000s, just-in-time () compilers and refined entry point management, as seen in Java's public static void main([] args) method, standardized since JDK 1.0 in 1996 but widely adopted with HotSpot's optimizations around 2000 for better performance. Java's model addressed multi-threading by initializing the main thread at this static entry before spawning others, integrating with class loaders for runtime . The PE format's influence persisted, standardizing entry RVAs across Windows applications and enabling seamless integration with -generated code in managed environments.

Usage Patterns

In Batch and Standalone Programs

In batch processing, the entry point is invoked by system schedulers, such as cron, which execute programs as independent processes at predetermined times without user intervention, prioritizing minimal input/output to enable quick termination and efficient handling of queued tasks. This approach stems from early batch computing practices, where programs run in isolation to maximize throughput on shared resources. The scheduler typically launches the executable via shell commands or direct system calls, passing control to the program's designated starting function upon loading. For standalone executables, the operating system directly invokes the entry point when the program is run from the command line or a similar non-interactive context, performing essential setup like allocation and environment initialization before proceeding to the core logic, all without requiring user prompts. This invocation replaces the calling process image with the new one, ensuring the entry point receives full control immediately after loading the executable file. Argument passing to the entry point in these scenarios relies on standardized mechanisms defined by , where the main function receives an argument count (argc), an of argument strings (argv) terminated by a , and optionally an environment (envp) for configuration details suited to isolated executions. The argv element conventionally holds the program name or , while envp provides access to system variables like PATH or custom settings, facilitating adaptability in batch or direct runs without interactive input. Representative examples include scientific simulations and tools, where the entry point initializes predefined workflows—such as command-line parameters for input files, allocating resources for computations, and directing output to files or logs—before executing the task and exiting to free system resources promptly. In environments, this structure supports batch runs of simulations that process large datasets in fixed sequences, emphasizing reliability and minimal overhead.

In Interactive and Modern Environments

In interactive environments, entry points facilitate dynamic, user-driven execution rather than linear flows, often through loops or event handlers that respond to inputs or triggers. The Python Read-Eval-Print Loop (REPL), for example, acts as the primary entry point for interactive programming, invoked by running the python command, which launches an interpreter loop displaying a >>> prompt for immediate code evaluation and execution until termination. Similarly, in web browsers, the load event on the Window object provides a critical entry point for JavaScript, firing after the full page—including stylesheets, images, and subframes—has loaded, enabling initialization of interactive features like dynamic content updates. Modern operating systems and container platforms integrate entry points to manage responsive application lifecycles. In Android, the onCreate() method serves as the foundational entry point for activities, called once during startup to handle essential tasks such as binding data to views, initializing variables, and associating with components like ViewModels, before transitioning to visible states. For container , Docker's ENTRYPOINT directive defines the default executable or script executed upon container launch, allowing customization of startup behaviors—such as environment setup or argument handling—while supporting overrides via runtime commands for flexibility in deployment. In distributed serverless paradigms, AWS Lambda's handler function constitutes the event-driven entry point, receiving invocation events and context data to process requests, such as uploading files to storage services, with the handler specified as filename.function_name for precise invocation control. Security in these environments prioritizes sandboxing at entry to constrain privileges and mitigate risks from untrusted inputs. Browsers inherently sandbox execution within isolated contexts, preventing scripts from accessing the host filesystem or other processes, thus limiting potential exploits during onload initialization. In Docker, entrypoint scripts should run as non-root users via USER directives and security options like --security-opt=no-new-privileges to block escalation, ensuring containerized processes remain isolated. For handlers in multi-tenant setups, 2020s trends emphasize tenant isolation through checks at invocation—such as validating access tokens—and of event data to prevent cross-tenant leaks in shared environments. The 2010s marked key advancements in , where configurable entry points via declarative manifests became central to . API gateways emerged as unified entry points, requests to backend services while enforcing and aggregating responses to minimize client latency. In Kubernetes, pod specifications in YAML manifests allow overriding Docker entrypoints with custom command and args fields, enabling tailored startup logic across distributed services without altering images. These patterns, building on early concepts from 2011-2014, supported decentralized architectures with polyglot services and lightweight protocols.

Relation to Exit Point

Defining the Exit Point

The exit point in a refers to the designated code path, instruction, or function call that initiates the termination of the program's execution, ensuring that resources are properly released and control is returned to the operating system or calling environment. This mechanism contrasts with the entry point, which marks the beginning of program execution. Exit points can be categorized into several types based on the nature of termination. Normal exits occur when the program completes successfully or intentionally, typically via a function like exit() that returns a status code such as 0 or EXIT_SUCCESS to indicate success. Abnormal exits happen due to errors or external interventions, often triggered by signals like SIGTERM, which force termination without standard cleanup. At the core of an exit point's operation are mechanics designed to maintain system integrity. These include flushing output buffers to prevent , freeing dynamically allocated to avoid leaks, closing open file descriptors, and propagating an code—usually an 8-bit —to the for evaluation via functions like wait(). In normal termination, registered cleanup functions (e.g., via atexit()) are executed in reverse order, and temporary files may be removed automatically.

Integration in Program Lifecycle

The program lifecycle encompasses three primary phases: initialization at the entry point, execution of core logic, and finalization at the exit point, forming a symmetric structure that promotes orderly resource handling and state management from startup to shutdown. This structure is invoked by the operating system, which calls the designated entry point—such as the main function in C—to begin execution, and concludes when the program returns control via the exit point, ensuring cleanup and status reporting to the runtime environment. Interactions between entry and exit points are facilitated through mechanisms that bridge initialization and termination; for instance, in C, the atexit function, typically registered during entry point execution, queues handler functions to execute automatically upon normal program exit via exit or return from main, enabling deferred cleanup without manual invocation at every termination path. Signals raised during core execution can lead to abnormal termination, potentially bypassing standard cleanup unless handled by signal handlers. As outlined in the definition of the exit point, this ensures that abrupt ends align with the program's overall flow. Resource management integrates entry and exit points by pairing allocation during initialization with deallocation at termination; for example, dynamic or file handles acquired in the entry phase must be released via exit handlers to prevent leaks, as mismatches can lead to resource exhaustion in long-running or repeated executions. In C, atexit supports this by allowing registration of deallocation routines at startup, which execute in reverse order of registration during exit, maintaining balance across the lifecycle. In advanced configurations, such as plugin systems or multithreaded environments, programs feature multiple entry points—like DLL entry via DllMain in Windows for process attachment—and corresponding exit points for detachment, necessitating synchronization primitives to coordinate lifecycle events and avoid conflicts during concurrent loading or unloading. For multithreaded programs, thread-specific entry points (e.g., functions passed to pthread_create in ) and exits (via pthread_exit) must synchronize with the main program's entry and exit to ensure collective resource release, often using mutexes or barriers to prevent premature termination or orphaned allocations.

Implementations in Programming Languages

Procedural and Imperative Languages

In procedural and imperative languages, the entry point serves as the designated starting location for program execution, typically initiated by the operating system after loading the and initializing global variables. This entry point often involves a runtime startup routine that sets up the environment before transferring control to the user-defined main function or equivalent. Common across these languages is the handling of global initialization, where static and global variables are allocated and initialized prior to invoking the entry point, ensuring a consistent state for imperative . In C and C++, the operating system entry point is commonly the _start symbol provided by the runtime library, such as in GNU's libc, which performs initial setup like stack allocation and argument passing before calling the user's main function. The main function signature is standardized as int main(int argc, char *argv[]) or int main(int argc, char *argv[], char *envp[]) in C++, where argc counts command-line arguments and argv is an array of argument strings; it returns an integer exit code to indicate program status to the OS. Explicit linking can override the default entry point using tools like the GNU linker (ld) with the --entry option to specify a custom symbol, allowing fine-grained control in embedded or low-level applications. FORTRAN, a foundational imperative language, defines the entry point through the PROGRAM statement, which marks the beginning of the main program unit and implies sequential execution from that line in fixed-form source code, where columns 1-5 are reserved for labels and column 6 for continuation indicators. The ANSI FORTRAN 77 standard formalized this structure, requiring the PROGRAM statement (optionally followed by a program name) as the entry for the primary executable unit, with execution proceeding imperatively through statements until an END or STOP directive. This design reflects FORTRAN's origins in scientific computing, prioritizing straightforward control flow without runtime argument handling in early versions. Pascal employs a program block structure for its entry point, beginning with a program declaration (optionally named) followed by a begin keyword to initiate the main statements, enclosed by an end to signal completion. This block-oriented approach enforces imperative sequencing, with global initialization occurring prior to entry as part of the compilation unit setup. Compiler directives, such as those in ISO Pascal or extensions in implementations like , allow configuration of the entry point for modular programs or runtime environments, enabling customization for different hardware targets.

Functional and Declarative Languages

In functional and declarative languages, entry points emphasize declarative specifications and immutability, where program execution begins through top-level forms or designated functions that encapsulate side effects within controlled structures like monads or uniqueness types, contrasting with imperative mutation. Haskell programs initiate execution from the main function in the Main module, which must have the type IO () to perform input/output actions while preserving referential transparency outside the IO monad. The Glasgow Haskell Compiler (GHC) runtime system initializes the program by invoking this main after setting up the runtime environment, ensuring lazy evaluation and garbage collection are active from the start. The IO monad, introduced in the early 1990s as a composable mechanism for side effects in pure functional languages, wraps imperative-style operations at the entry point to maintain purity elsewhere. In , there is no fixed entry point like a mandatory main; instead, execution often starts by evaluating top-level forms upon loading the file, or by specifying a toplevel function such as (defun main () ...) for standalone executables. Load-time evaluation, controlled via the eval-when special form with phases like :load-toplevel and :execute, ensures that initialization code—such as loading dependencies—runs when the image is dumped or the program starts, supporting dynamic environments typical of variants. OCaml, blending functional and imperative paradigms, uses a top-level expression like let () = main () as the entry point, where main is a unit-returning function that triggers the program's primary logic without binding a value to a name. In compilation with ocamlc, the runtime ocamlrun interprets the code sequentially from the loaded modules, while native compilation via ocamlopt produces standalone executables where entry points are determined by the linking order of .cmx files, raising errors if dependencies are unresolved at link time. Clean, a purely functional with by default, requires a Start rule defined in definition modules (.dcl files) as the explicit entry point, which computes the program's world state transitions while delaying evaluation until results are needed. This approach, leveraging uniqueness types for safe side effects, postpones entry point effects until demanded, aligning with advancements in type-safe I/O for declarative languages.

Object-Oriented and Scripting Languages

In object-oriented languages like and C#, the entry point is typically a designated static method within a class that the runtime environment invokes to begin program execution. In , the (JVM) starts execution by calling the public static void main(String[] args) method in the specified class, which serves as the bootstrap entry for standalone applications. This method must reside in a class and accepts command-line arguments via the args , enabling the program to process inputs immediately upon launch. The JVM identifies this entry point through the manifest's Main-Class header or direct class specification, ensuring encapsulated object initialization occurs from this static context before instance creation. Similarly, in C# running on the .NET (CLR), the entry point is the static void Main([string](/page/String)[] args) method, which the runtime invokes first in console or executable applications. This method initializes the application's object-oriented structure, including garbage collection setup and static constructors, allowing developers to orchestrate class loading and from a central point. Since C# 7.1, this entry point supports asynchronous execution with static async Task Main([string](/page/String)[] args), facilitating non-blocking I/O operations at startup, such as database connections or calls, without altering the core lifecycle. The CLR handles garbage collection initialization concurrently with this entry, optimizing in object-heavy environments. Scripting languages, often dynamically typed and interpreted, emphasize flexibility in entry points to support rapid development and runtime evaluation. In Python, scripts execute from the top-level code, but the conventional entry point is guarded by the if __name__ == "__main__":, which runs a main() function or block only when the module is invoked directly rather than imported. This approach leverages the interpreter's execution model, where the __main__ module is set upon direct run (e.g., python script.py), enabling reusable code with isolated script behavior and supporting garbage collection from the outset. Python's interpreter initializes its runtime environment, including the global , at this entry, accommodating dynamic object creation without strict class requirements. PHP scripts, commonly used for web and command-line tasks, begin execution from the first line after the opening <?php tag, serving as the implicit entry point without a formal method declaration. In CLI mode, invoked via php script.php, the interpreter processes the entire file sequentially, initializing the superglobals $argc and $argv from command-line arguments and setting up garbage collection for dynamic variables; this differs from invocation, where the entry aligns with HTTP request handling but still starts at the script's top. The CLI binary, distinct from CGI, ensures standalone execution with shebang support (e.g., #!/usr/bin/php) for direct invocation, emphasizing PHP's runtime flexibility over rigid object encapsulation. Ruby and Perl, as interpreted scripting languages, lack a mandatory entry method, with execution commencing at the file's top line upon invocation (e.g., ruby script.rb or perl script.pl), allowing immediate dynamic code evaluation and object instantiation. In Ruby, developers often use if &#36;0 == __FILE__ to demarcate script-specific code, mirroring Python's guard while the interpreter handles garbage collection and module loading from this starting point. Perl follows suit, processing the script line-by-line after optional shebang, with the runtime initializing its and at entry for procedural or object-oriented extensions. These designs prioritize scripting efficiency, enabling quick prototyping with runtime garbage collection tailored to dynamic typing. In the 2010s, Node.js's event-driven asynchronous model influenced scripting entry points, promoting top-level async constructs like async function main() in modules for non-blocking starts, which inspired similar updates in languages such as Python's asyncio integration within __main__ blocks and C#'s async Main for containerized scripts. This evolution supports modern, container-friendly deployments where entry points handle asynchronous initialization efficiently, reducing latency in I/O-bound applications.

Other Notable Languages

In APL, traditional defined functions (tradfns) are delimited by the Del symbol (∇), which marks the beginning and end of the function definition, allowing for with headers specifying arguments and results. The APL interpreter typically executes scripts starting from line 0 in numbered line mode, serving as the implicit entry point for sequential evaluation. The Go programming language designates the entry point as the func main() within a package main, which the automatically identifies and links as the program's starting function. Prior to main, any init() functions in packages execute sequentially, and these may launch goroutines for concurrent initialization, ensuring the runtime environment is prepared before the primary entry. Rust uses fn main() as the conventional entry point for executable binaries, invoked by the runtime after static initializers. For foreign function interfaces or custom linking, functions can be marked with #[no_mangle] to preserve names without Rust's symbol mangling, and 's linker specifications in Cargo.toml or build scripts allow overriding the default entry for embedded or low-level targets. Swift employs the @main attribute to designate the program's entry point, applied to a type conforming to App for applications or a delegate class, streamlining launch from the 2010s onward with a focus on and macOS ecosystems. Similarly, Dart relies on a top-level main() function as the entry point, returning void and optionally accepting command-line arguments, integral to its design for web and mobile apps since the . The D language also centers on main() as the entry point for console programs, executed after module initializers and unittests, supporting with C-like compatibility. In implementations of , the entry point is the executed script file (often index.js), where top-level code runs immediately, and module.exports exposes functions or objects for modular reuse across files. , the Ada compiler, treats the main procedure as the primary entry point within the main task, with additional tasks enabling concurrent execution via task bodies activated at elaboration; custom entries require linker flags like -e. LOGO, an educational language from the , operates interactively without a strict compiled entry point, instead beginning execution via primitive commands like TO for defining procedures or direct invocation of built-in primitives such as FORWARD and REPEAT in the listener. QB64, a modern variant, defaults to executing from the first non-declaration line but supports SUB Main as an explicit entry subroutine for structured programs, callable at startup. Visual Basic applications start at the Main procedure, which controls initialization and often launches the startup form for GUI programs, as defined in project settings. In Xojo, desktop applications enter via the App class's Open event, which typically shows the initial window or form, supporting cross-platform development. Pike executes top-level code in scripts as the entry point, with no mandatory main function, aligning its dynamic nature for server and multimedia uses. For modules in the 2020s, especially under WASI, the entry point is often the exported _start function for command-line executables, invoked after imports and before other exports, enabling portable systems code. transpiles to , preserving the entry point as the compiled main function or top-level code in the output, configurable via tsconfig.json for module systems like or ES modules.

References

Add your contribution
Related Hubs
User Avatar
No comments yet.