Clang warning: ISO C++ does not allow 'main' to be used by a program [-Wmain] (ext_main_used)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: ISO C++ does not allow 'main' to be used by a program
Type Warning
Category Semantic Issue
Internal Id ext_main_used
Active by Default No
Flags -Wmain (7 elements)
-Wpedantic (151 elements)
Internal Message ISO C++ does not allow 'main' to be used by a program
Regular Expression (?:warning|error|fatal error)\: ISO C\+\+ does not allow 'main' to be used by a program \[(?:\-Werror,)?\-Wmain[^\]]*\]
First Commit 2014-01-22 b63b6ee9a00e Enforce restrictions that 'main' is not allowed to be deleted, or to be used by

Description

The warning is issued by the Clang compiler when a program directly uses the main function in a context not allowed by the ISO C++ standard. This generally involves attempts to call main recursively, or to take its address. The C++ standard specifies that the main function shall not be used within a program, except for being called by the system as the starting point of the program. The restriction is designed to ensure the orderly initialization and termination of C++ programs, with main serving as a unique entry and exit point.

While the C++ standard prohibits these uses of main, some compilers might provide extensions that allow such behavior. The Clang compiler, in particular, can emit this warning to alert users that their code is not portable or does not adhere to standard C++ practices. However, Clang also supports certain extensions to maintain compatibility with other compilers and existing codebases that rely on non-standard usage of main. This warning can be controlled through the use of specific compiler flags that either disable the warning or treat it as an error, to enforce stricter compliance with the C++ standard.

 
AI Generated

Example

In the following example, the program defines the main function and then proceeds to call main recursively within itself. This action violates the ISO C++ standard, which prohibits the use of the main function in such a manner. Specifically, the standard stipulates that main cannot be called recursively, nor can its address be taken, to ensure that main serves as the unique entry and exit point for C++ programs. The Clang compiler detects this non-standard usage and issues a warning, signaling that the code is not portable and does not adhere to standard C++ practices.  
AI Generated


Flags -xc++ -Wmain

[Try out in Compiler Explorer]

Source
int main() {
  // Recursion
  main();
  return 0;
}
Compiler Output
<source>:3:3: warning: ISO C++ does not allow 'main' to be used by a program [-Wmain]


Clang Internals (17.0.6)

Git Commit Message

Enforce restrictions that 'main' is not allowed to be deleted, or to be used by
the program, in C++. (We allow the latter as an extension, since we've always
permitted it, and GCC does the same, and our supported C++ ABIs don't do
anything special in main.)

llvm-svn: 199782

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaExpr.cpp (line 248)

/// Determine whether the use of this declaration is valid, and
/// emit any corresponding diagnostics.
///
/// This routine diagnoses various problems with referencing
/// declarations that can occur when using a declaration. For example,
/// it might warn if a deprecated or unavailable declaration is being
/// used, or produce an error (and return true) if a C++0x deleted
/// function is being used.
///
/// \returns true if there was an error (this declaration cannot be
/// referenced), false otherwise.
///
bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs, const ObjCInterfaceDecl *UnknownObjCClass, bool ObjCPropertyAccess, bool AvoidPartialAvailabilityChecks, ObjCInterfaceDecl *ClassReceiver, bool SkipTrailingRequiresClause) {
  // ...
  if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) {
    // ...
    // C++ [basic.start.main]p3:
    //   The function 'main' shall not be used within a program.
    if (cast<FunctionDecl>(D)->isMain())
      Diag(Loc, diag::ext_main_used);

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/CXX/basic/basic.start/basic.start.init/p3.cpp

  • clang/test/CXX/basic/basic.start/basic.start.init/p3.cpp:19:32: error: ISO C++ does not allow 'main' to be used by a program [-Werror,-Wmain]
  • clang/test/CXX/basic/basic.start/basic.start.init/p3.cpp:22:5: error: ISO C++ does not allow 'main' to be used by a program [-Werror,-Wmain]