C++ syntax: Difference between revisions

Content deleted Content added
No edit summary
Tags: Mobile edit Mobile web edit
 
(47 intermediate revisions by 15 users not shown)
Line 3:
[[File:Orwell Dev-Cpp zh cn.jpg|thumb|300px|A snippet of C++ code]]
 
The '''syntax of C++''' is [[syntax|the set of rules]] defining how a [[C++]] program is written and compiled.
 
C++ syntax is largely inherited from the syntax of its ancestor language [[C (programming language)|C]], and has influenced the syntax of several later languages including but not limited to [[Java (programming language)|Java]], [[C Sharp (programming language)|C#]], and [[Rust (programming language)|Rust]].
Line 9:
== Basics ==
Much of C++'s syntax aligns with [[C syntax]], as C++ provides backwards compatibility with C.
 
The C++ [["Hello, World!" program]] program is as follows:<ref name="cppreferencehelloworld">{{Cite web|url=https://en.cppreference.com/w/cpp/io/println|title=std::println|website=cppreference.com}}</ref>
<syntaxhighlight lang="cpp">
import std;
 
int main() {
std::println("Hello, world!");
}
</syntaxhighlight>
 
=== Identifier ===
Line 29 ⟶ 38:
* <code>alignas</code>
* <code>alignof</code>
* <code>and</code>
* <code>and_eq</code>
* <code>asm</code>
* <code>auto</code>
* <code>bitand</code>
* <code>bitor</code>
* <code>bool</code>
* <code>break</code>
Line 44 ⟶ 49:
* <code>char32_t</code>
* <code>class</code>
* <code>compl</code>
* <code>concept</code>
* <code>const</code>
Line 57 ⟶ 61:
* <code>co_yield</code>
* <code>decltype</code>
* <code>default</code>
* <code>default</code>
* <code>do</code>
Line 82 ⟶ 85:
* <code>new</code>
* <code>noexcept</code>
* <code>not</code>
* <code>not_eq</code>
* <code>nullptr</code>
* <code>operator</code>
* <code>or</code>
* <code>or_eq</code>
* <code>private</code>
* <code>protected</code>
Line 120 ⟶ 119:
* <code>wchar_t</code>
* <code>while</code>
{{div col end}}
 
The keyword [[restrict|<code>restrict</code>]], though present in C, is not standard in C++, though some compilers may support it. The keyword <code>fortran</code>, a conditionally supported keyword in C which denotes linkage for the [[Fortran]] programming language, is conditionally supported in C++.
 
=== Alternative operator keywords ===
The following words are reserved keywords, but are used as alternative spellings for operators and tokens that use non-ISO646 characters.
{{div col|colwidth=15em}}
* <code>and</code>
* <code>and_eq</code>
* <code>bitand</code>
* <code>bitor</code>
* <code>compl</code>
* <code>not</code>
* <code>not_eq</code>
* <code>or</code>
* <code>or_eq</code>
* <code>xor</code>
* <code>xor_eq</code>
Line 154 ⟶ 169:
* <code>#warning</code>
* <code>#pragma</code>
* <code>#defined</code> (follows a conditional directive)
* <code>#__has_include</code>
* <code>#__has_cpp_attribute</code>
* <code>#__has_embed</code>
{{div col end}}
 
The following macros are often ubiquitously used in C and thus C++ as well:
* <code>NULL</code> (expands to <code>(void*)0</code>, used prior to the introduction of <code>nullptr</code> to represent a null pointer)
* <code>NDEBUG</code> (a macro meaning "no-debug", used primarily to control whether <code>assert()</code> calls are ignored)
* <code>assert()</code> (a macro with arguments, which terminates the program if the argument evaluates to <code>false</code>, <code>0</code>, or <code>nullptr</code>, and can be disabled by <code>NDEBUG</code>)
 
=== Code blocks ===
Line 182 ⟶ 202:
C++ has two kinds of [[Comment (computer programming)|comments]]: ''traditional comments'' and ''end-of-line comments''.
 
Traditional comments, also known as block comments, start with <code>/*</code> and end with <code>*/</code>, they may span across multiple lines.
 
<syntaxhighlight lang="cpp">
Line 224 ⟶ 244:
 
int main(int argc, char* argv[]) {
std::println("argc = {}", argc);
for (size_t i = 0; i < argc; ++i) {
std::println("argv[{}] = {}", i, argv[i]);
}
}
</syntaxhighlight>
Line 259 ⟶ 280:
These objects have a dynamic lifespan and can be created directly with a call to {{cpp|new}} and destroyed explicitly with a call to {{cpp|delete}}.<ref name="C++11 3.7.4">[[International Organization for Standardization|ISO]]/[[International Electrotechnical Commission|IEC]]. ''[https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf Programming Languages – C++11 Draft (n3797)] {{Webarchive|url=https://web.archive.org/web/20181002093659/http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf |date=2 October 2018 }} §3.7.4 Dynamic Storage duration <nowiki>[</nowiki>basic.stc.dynamic<nowiki>]</nowiki>''</ref> C++ also supports <code>malloc</code> and <code>free</code>, from C, but these are not compatible with {{cpp|new}} and {{cpp|delete}}. Use of {{cpp|new}} returns an address to the allocated memory. The C++ Core Guidelines advise against using {{cpp|new}} directly for creating dynamic objects in favor of smart pointers through {{cpp|make_unique<T>}} for single ownership and {{cpp|make_shared<T>}} for reference-counted multiple ownership,<ref>{{Cite web |url=https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r11-avoid-calling-new-and-delete-explicitly |title=C++ Core Guidelines |website=isocpp.github.io |access-date=2020-02-09 |archive-date=8 February 2020 |archive-url=https://web.archive.org/web/20200208160101/http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r11-avoid-calling-new-and-delete-explicitly |url-status=live}}</ref> which were introduced in C++11.
 
== Inline AssemblyInteroperability ==
=== With C ===
Programs developed in C or C++ often utilize inline assembly to take advantage of its low-level functionalities, greater speed, and enhanced control compared to high-level programming languages<ref name="Bokil2021">Bokil, Milind A. (2021). "[https://www.researchgate.net/publication/354744729_Writing_Assembly_Routines_within_CC_and_Java_Programs Writing Assembly Routines within C/C++ and Java Programs]". ResearchGate. Retrieved April 1, 2025.</ref><ref name="Vilhena2024">Vilhena, Paulo Emílio de; Lahav, Ori; Vafeiadis, Viktor; Raad, Azalea (2024). "[https://doi.org/10.1145/3689749 Extending the C/C++ Memory Model with Inline Assembly]". Proceedings of the ACM on Programming Languages, Vol. 8, OOPSLA2, Article 309. doi:10.1145/3689749.</ref> when optimizing for performance is essential. C++ provides support for embedding [[Assembly language|assembly]] language using asm declarations<ref name="cppreferenceAsm">cppreference.com contributors. "[https://en.cppreference.com/w/cpp/language/asm asm declaration]". ''cppreference.com''. Retrieved April 1, 2025.</ref>, but the compatibility of [[inline assembly]] varies significantly between [[compilers]] and architectures. Unlike high-level language features such as [[Python (programming language)|Python]] or [[Java (programming language) |Java]], assembly code is highly dependent on the underlying processor and compiler implementation.
{{main|Compatibility of C and C++}}
C++ is often considered to be a superset of [[C (programming language)|C]] but this is not strictly true.<ref name="superset">{{cite web |url=http://www.stroustrup.com/bs_faq.html#C-is-subset |title=Bjarne Stroustrup's FAQ&nbsp;– Is C a subset of C++? |access-date=5 May 2014 |archive-date=6 February 2016 |archive-url=https://web.archive.org/web/20160206214150/http://www.stroustrup.com/bs_faq.html#C-is-subset |url-status=live }}</ref> Most C code can easily be made to compile correctly in C++ but there are a few differences that cause some valid C code to be invalid or behave differently in C++. For example, C allows implicit conversion from <syntaxhighlight lang="C++" inline>void*</syntaxhighlight> to other pointer types but C++ does not (for type safety reasons). Also, C++ defines many new keywords, such as <syntaxhighlight lang="C++" inline>new</syntaxhighlight> and <syntaxhighlight lang="C++" inline>class</syntaxhighlight>, which may be used as identifiers (for example, variable names) in a C program.
 
Some incompatibilities have been removed by the 1999 revision of the C standard ([[C99]]), which now supports C++ features such as line comments (<syntaxhighlight lang="C++" inline>//</syntaxhighlight>) and declarations mixed with code. On the other hand, C99 introduced a number of new features that C++ did not support that were incompatible or redundant in C++, such as [[variable-length array]]s, native complex-number types (however, the <syntaxhighlight lang="C++" inline>std::complex</syntaxhighlight> class in the C++ standard library provides similar functionality, although not code-compatible), designated initializers, [[C syntax#Compound literals|compound literals]], and the <syntaxhighlight lang="C++" inline>restrict</syntaxhighlight> keyword.<ref>{{cite web |url=http://home.datacomm.ch/t_wolf/tw/c/c9x_changes.html |title=C9X – The New C Standard |access-date=27 December 2008 |archive-date=21 June 2018 |archive-url=https://web.archive.org/web/20180621084656/http://home.datacomm.ch/t_wolf/tw/c/c9x_changes.html |url-status=live }}</ref> Some of the C99-introduced features were included in the subsequent version of the C++ standard, [[C++11#Improved C compatibility|C++11]] (out of those which were not redundant).<ref>{{cite web |title=C++0x Support in GCC |url=https://gcc.gnu.org/projects/cxx0x.html |access-date=12 October 2010 |archive-date=21 July 2010 |archive-url=https://web.archive.org/web/20100721215324/http://gcc.gnu.org/projects/cxx0x.html |url-status=live }}</ref><ref>{{cite web |title=C++0x Core Language Features In VC10: The Table |url=https://blogs.msdn.com/b/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx |access-date=12 October 2010 |archive-date=21 August 2010 |archive-url=https://web.archive.org/web/20100821114635/http://blogs.msdn.com/b/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx |url-status=live }}</ref><ref>{{cite web |url=https://clang.llvm.org/cxx_status.html |title=Clang - C++98, C++11, and C++14 Status |publisher=Clang.llvm.org |date=12 May 2013 |access-date=10 June 2013 |archive-date=4 July 2013 |archive-url=https://web.archive.org/web/20130704124639/http://clang.llvm.org/cxx_status.html |url-status=live }}</ref> However, the C++11 standard introduces new incompatibilities, such as disallowing assignment of a string literal to a character pointer, which remains valid C.
=== Variations across compilers ===
Different C++ compilers implement inline assembly in distinct ways.
 
To intermix C and C++ code, any function declaration or definition that is to be called from/used both in C and C++ must be declared with C linkage by placing it within an <syntaxhighlight style=white-space:nowrap lang="C++" inline>extern "C" {/*...*/}</syntaxhighlight> block. Such a function may not rely on features depending on [[name mangling]] (i.e., function overloading).
*GCC ([[GNU Compiler Collection]]) and [[Clang]] <ref>{{Cite web |title=Extended Asm (Using the GNU Compiler Collection) |url=https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html |website=GCC Online Documentation |publisher=GNU Project |access-date=April 1, 2025}}</ref>: Use the GCC extended inline assembly syntax. Using <syntaxhighlight lang="C++" inline>__asm__</syntaxhighlight> keyword instead of <syntaxhighlight lang="C++" inline>asm</syntaxhighlight> when writing code that can be compiled with <syntaxhighlight lang="C++" inline>-ansi</syntaxhighlight> and <syntaxhighlight lang="C++" inline>-std</syntaxhighlight> options, which allows specifying input/output operands and clobbered registers. This approach is widely adopted, including by Intel<ref name="IntelInlineAssembly">Intel Corporation. "[https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-9/inline-assembly.html Inline Assembly]". ''Intel® C++ Compiler Classic Developer Guide and Reference'', Version 2021.9. Retrieved April 1, 2025.</ref> and IBM<ref name="IBMInlineAssembly">IBM. "[https://www.ibm.com/docs/en/xl-c-aix/13.1.3?topic=statements-inline-assembly-extension Inline assembly statements (IBM extension)]". ''IBM Documentation''. Retrieved April 1, 2025.</ref> compilers.
 
=== Inline Assembly ===
*MSVC ([[Microsoft Visual C++]]): The inline assembler is built into the compiler. Previously supported inline assembly via the <syntaxhighlight lang="C++" inline>__asm</syntaxhighlight> keyword, but this support has been removed in 64-bit mode, requiring separate .asm modules instead<ref>{{Cite web |title=Inline Assembler Overview |url=https://learn.microsoft.com/en-us/cpp/assembler/inline/inline-assembler-overview?view=msvc-170 |website=Microsoft Learn |publisher=Microsoft |access-date=1 April 2025}}</ref>.
Programs developed in C or C++ often utilize inline assembly to take advantage of its low-level functionalities, greater speed, and enhanced control compared to high-level programming languages<ref name="Bokil2021">Bokil, Milind A. (2021). "[https://www.researchgate.net/publication/354744729_Writing_Assembly_Routines_within_CC_and_Java_Programs Writing Assembly Routines within C/C++ and Java Programs]". ResearchGate. Retrieved April 1, 2025.</ref><ref name="Vilhena2024">{{cite journal | url=https://doi.org/10.1145/3689749 | doi=10.1145/3689749 | title=Extending the C/C++ Memory Model with Inline Assembly | date=2024 | last1=De Vilhena | first1=Paulo Emílio | last2=Lahav | first2=Ori | last3=Vafeiadis | first3=Viktor | last4=Raad | first4=Azalea | journal=Proceedings of the ACM on Programming Languages | volume=8 | pages=1081–1107 | arxiv=2408.17208 }}</ref> when optimizing for performance is essential. C++ provides support for embedding [[Assembly language|assembly]] language using asm declarations,<ref name="cppreferenceAsm">cppreference.com contributors. "[https://en.cppreference.com/w/cpp/language/asm asm declaration]". ''cppreference.com''. Retrieved April 1, 2025.</ref> but the compatibility of [[inline assembly]] varies significantly between [[compilers]] and architectures. Unlike high-level language features such as [[Python (programming language)|Python]] or [[Java (programming language)|Java]], assembly code is highly dependent on the underlying processor and compiler implementation.
 
==== Variations across compilers ====
Different C++ compilers implement inline assembly in distinct ways.
 
*GCC ([[GNU Compiler Collection]]) and [[Clang]]:<ref>{{Cite web |title=Extended Asm (Using the GNU Compiler Collection) |url=https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html |website=GCC Online Documentation |publisher=GNU Project |access-date=April 1, 2025}}</ref> Use the GCC extended inline assembly syntax. Using <syntaxhighlight lang="C++" inline>__asm__</syntaxhighlight> keyword instead of <syntaxhighlight lang="C++" inline>asm</syntaxhighlight> when writing code that can be compiled with <syntaxhighlight lang="C++" inline>-ansi</syntaxhighlight> and <syntaxhighlight lang="C++" inline>-std</syntaxhighlight> options, which allows specifying input/output operands and clobbered registers. This approach is widely adopted, including by Intel<ref name="IntelInlineAssembly">Intel Corporation. "[https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-9/inline-assembly.html Inline Assembly]". ''Intel® C++ Compiler Classic Developer Guide and Reference'', Version 2021.9. Retrieved April 1, 2025.</ref> and IBM<ref name="IBMInlineAssembly">IBM. "[https://www.ibm.com/docs/en/xl-c-aix/13.1.3?topic=statements-inline-assembly-extension Inline assembly statements (IBM extension)]". ''IBM Documentation''. Retrieved April 1, 2025.</ref> compilers.
*TI ARM Clang and Embedded Compilers <ref>{{Cite web |title=Interfacing C and C++ With Assembly Language |url=https://software-dl.ti.com/codegen/docs/tiarmclang/compiler_tools_user_guide/compiler_manual/runtime_environment/interfacing-c-and-c-with-assembly-language-stdz0544217.html#interfacing-c-and-c-with-assembly-language |website=Texas Instruments |publisher=Texas Instruments Incorporated |date=February 23, 2025 |access-date=April 1, 2025}}</ref>: Some embedded system compilers, like Texas Instruments' TI Arm Clang, allow inline assembly but impose stricter rules to avoid conflicts with register conventions and calling conventions.
*MSVC ([[Microsoft Visual C++]]): The inline assembler is built into the compiler. Previously supported inline assembly via the <syntaxhighlight lang="C++" inline>__asm</syntaxhighlight> keyword, but this support has been removed in 64-bit mode, requiring separate .asm modules instead.<ref>{{Cite web |title=Inline Assembler Overview |url=https://learn.microsoft.com/en-us/cpp/assembler/inline/inline-assembler-overview?view=msvc-170 |website=Microsoft Learn |publisher=Microsoft |access-date=1 April 2025}}</ref>
*TI ARM Clang and Embedded Compilers:<ref>{{Cite web |title=Interfacing C and C++ With Assembly Language |url=https://software-dl.ti.com/codegen/docs/tiarmclang/compiler_tools_user_guide/compiler_manual/runtime_environment/interfacing-c-and-c-with-assembly-language-stdz0544217.html#interfacing-c-and-c-with-assembly-language |website=Texas Instruments |publisher=Texas Instruments Incorporated |date=February 23, 2025 |access-date=April 1, 2025}}</ref> Some embedded system compilers, like Texas Instruments' TI Arm Clang, allow inline assembly but impose stricter rules to avoid conflicts with register conventions and calling conventions.
 
==== Interoperability between C++ and Assembly ====
C++ provides two primary methods of integrating ASM code.
 
1. Standalone assembly files – Assembly code is written separately and linked with C++ code. <ref>{{cite web |url=https://wiki.osdev.org/C%2B%2B_to_ASM_linkage_in_GCC |title=C++ to ASM linkage in GCC |website=OSDev Wiki |access-date=1 April 2025}}</ref>
 
2. [[Inline assembly]] – Assembly code is embedded within C++ code using compiler-specific extensions.
Line 483 ⟶ 511:
</syntaxhighlight>
 
It is also possible to raise exceptions purposefully, using the <syntaxhighlight lang="C++" inline>throw</syntaxhighlight> keyword; these exceptions are handled in the usual way. In some cases, exceptions cannot be used due to technical reasons. One such example is a critical component of an embedded system, where every operation must be guaranteed to complete within a specified amount of time. This cannot be determined with exceptions as no tools exist to determine the maximum time required for an exception to be handled.<ref>{{Cite book |title=The C++ Programming Language |last=Stroustrup |first=Bjarne |publisher=Addison Wesley |year=2013 |isbn=9780321563842 |pages=349}}</ref> Unlike languages like Java, C# and D, which only allows objects that extend <code>Throwable</code> (whose subclasses are <code>Error</code> and <code>Exception</code>), C++ allows anything, both primitive types and objects, to be thrown and caught. C++ does not have an Error class like those languages, but has an Exception class (<code>std::exception</code>). In the aforementioned languages, the distinction between Error and Exception is made in that Errors usually represent irrecoverable states, while Exceptions are more acceptable to catch and represent circumstances that are normal to occur throughout the execution of a program.
 
Unlike [[Signal handler|signal handling]], in which the handling function is called from the point of failure, exception handling exits the current scope before the catch block is entered, which may be located in the current function or any of the previous function calls currently on the stack.
Line 492 ⟶ 520:
== Concepts ==
{{main|Concepts (C++)}}
Concepts are an extension to the [[template (C++)|templates]] feature provided by the [[C++]] programming language. Concepts are named [[Boolean value|Boolean]] predicates on template parameters, evaluated at [[compile time]]. A concept may be associated with a template ([[class (C++)|class]] template, [[function (computer programming)|function]] template, [[member function]] of a class template, [[Template _ (C%2B%2B++)#Variable_templatesVariable templates|variable template]], or [[Template_Template (C%2B%2B++)#Template_aliasesTemplate aliases|alias template]]), in which case it serves as a ''constraint'': it limits the set of arguments that are accepted as template parameters.
 
The main uses of concepts are:
Line 511 ⟶ 539:
* <code>C1</code>: A type-constraint. This kind replaces <code>class</code> or [[Typename|<code>typename</code>]] for declaring a [[TypeParameter|type template parameter]]. When using a concept instead of the former two the type is constraint.
* <code>C2</code>: A requires-clause. Whenever a type-constraint does not work, for example, because the concept takes multiple parameters, a requires-clause can be used to apply more elaborated constraints.
* <code>C3 / C4</code>: A constrained placeholder type. The same syntax is available for [[Type_inferenceType inference|placeholder]] variable aka. <code>auto</code> variable. C++20 added [[abbreviated function template]]s which use <code>auto</code> as a placeholder type in the parameter declaration.<ref>{{ cite web | title = ISO/IEC 14882:2020 | publisher = ISO | date = December 2020 | url = http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=79358 | access-date =14 July 2022 }}</ref> A constrained placeholder type allows to put constraints on the automatically deduced return type of a function or a variable.
* <code>C5</code>: A trailing requires-clause. This form is similar to <code>C2</code> with one notable exception. A trailing requires-clause can be applied to a function in a class template. This allows the function to remain a regular, template-free function, which can be enabled or disabled depending on the functions trailing requires-clause.
 
Line 519 ⟶ 547:
=== Headers ===
{{see also|Include directive}}
Traditionally (prior to [[C++20]]), code inclusion in C++ followed the ways of C, in which code was imported into another file using the preprocessor directive <code>#include</code>, which would copy the contents of the file into the other file.
 
Traditionally, C++ code would be divided between a header file (typically with extension {{mono|.h}}, {{mono|.hpp}} or {{mono|.hh}}) and a source file (typically with extension {{mono|.cpp}} or {{mono|.cc}}). The header file usually contained declarations of symbols while the source file contained the actual implementation, such as function implementations. This separation was often enforced because <code>#include</code>ing code into another file would result in it being reprocessed for each file it was included by, resulting in increased compilation times if the compiler had to reprocess the same source repeatedly.
 
Headers often also forced the usage of [[include guard|{{mono|#include}} guards]] or [[pragma once|{{mono|#pragma once}}]] to prevent a header from potentially being included into a file multiple times.
 
The C++ standard library remains accessible through headers, however since C++23 it has been made accessible using modules as well.<ref name=cppreferencemodules /><ref name=cppreferencestandardlibrary /> Even with the introduction of modules, headers continue to play a role in modern C++, as existing codebases have not completely migrated to modules.
 
==== Header units ====
Headers are traditionally included via textual inclusion by the preprocessor using <code>#include</code>, while modules are included during compilation through <code>import</code>. However, headers may also be imported using <code>import</code>, even if they are not declared as modules – these are called "header units", and they are designed to allow existing codebases to migrate from headers to modules more gradually.<ref>{{cite web|url=https://learn.microsoft.com/en-us/cpp/build/walkthrough-header-units?view=msvc-170|title=Walkthrough: Build and import header units in Microsoft Visual C++|date=12 April 2022 |publisher=Microsoft}}</ref> The syntax is similar to including a header, with the difference being that <code>#include</code> is replaced with <code>import</code> and a semicolon is placed at the end of the statement. Header units automatically export all symbols, and differ from proper modules in that they allow the emittance of macros, meaning all who import the header unit will obtain its contained macros. This offers minimal breakage between migration to modules. The semantics of searching for the file depending on whether quotation marks or angle brackets are used apply here as well. For instance, one may write <syntaxhighlight lang="C++" inline>import <string>;</syntaxhighlight> to import the <code><string></code> header, or <syntaxhighlight lang="C++" inline>import "MyHeader.h";</syntaxhighlight> to import the file <code>"MyHeader.h"</code> as a header unit. Most build systems, such as [[CMake]], do not support this feature yet.
 
=== Modules ===
{{main|Modules (C++)}}
{{excerpt|Precompiled header|Modules}}
Modules do not use the C preprocessor at all, and are instead handled directly by the compiler.<ref name=cppreferencemodules /> A module is declared using <code>export module</code>, and the beginning of the module preamble begins with <code>module;</code>. Exported symbols which will be made accessible to importing translation units are marked <code>export</code>, and a module is imported into the translation unit using <code>import</code>. Modules do not export macros, due to being handled after the preprocessing step.
 
Modules may also have partitions, which cannot be imported individually but are owned by a larger module.
 
==== Example ====
{{excerpt|Modules (C++)|Example}}
A simple example of using C++ modules is as follows:
 
== Attributes ==
{{mono|Hello.cppm}}
Since C++11, C++ has supported attribute specifier sequences.<ref>{{cite web|title=Attribute specifier sequence (since C++11)|url=https://cppreference.com/w/cpp/language/attributes.html|website=cppreference.com|access-date=6 June 2025}}</ref> Attributes can be applied to any symbol that supports them, including classes, functions/methods, and variables, and any symbol marked with an attribute will be specifically treated by the compiler as necessary. These can be thought of as similar to [[Java annotation]]s for providing additional information to the compiler, however they differ in that attributes in C++ are not metadata that is meant to be accessed using reflection. C++26 adds support for annotations for reflection. Furthermore, one cannot create custom attributes in C++, unlike in Java where one may define custom annotations in addition to the standard ones. However, C++ does have implementation/vendor-specific attributes which are non-standard. These typically have a namespace associated with them. For instance, GCC and Clang have attributes under the <code>gnu::</code> namespace, and all such attributes are of the form {{cpp|[[gnu::*]]}}.
<syntaxhighlight lang="cpp">
export module myproject.Hello;
 
One may apply multiple attributes as a list, for instance {{cpp|[[A, B, C]]}} (where <code>A</code>, <code>B</code>, and <code>C</code> are attributes). Furthermore, attributes may also accept arguments, like {{cpp|[[A("This is a parameter")]]}}. The following is an example of using some attributes in C++.
import std;
 
<syntaxhighlight lang="cpp">
export namespace hello {
class MyObject {
void printHello() {
private:
std::println("Hello world!");
[[no_unique_address]]
int x;
public:
[[nodiscard]]
bool satisfiesProperty() const noexcept {
if ([[likely]] x > 0) {
return true;
}
return false;
}
};
</syntaxhighlight>
 
=== Standard attributes ===
{{mono|Main.cpp}}
The C++ standard defines the following attributes:
 
Legend:<br>
{{color box|#E6E6B7}}: Deprecated<br>
{{color box|#F99}}: Removed
 
{| class="wikitable"
! Name !! Description
|-
| {{cpp|[[noreturn]]}}
|| Indicates that the specified function will not return to its caller.
|-
| style="background:#F99" | {{cpp|[[carries_dependency]]}}
| style="background:#F99" | Indicates that the dependency chain in release-consume <code>std::memory_order</code> propagates in and out of the function. Removed since C++26.
|-
| {{cpp|[[deprecated]]}}<br>{{cpp|[[deprecated("reason")]]}}
|| Indicates that the use of the marked symbol is allowed but discouraged/deprecated for the reason specified (if given).
|-
| {{cpp|[[fallthrough]]}}
|| Indicates that the fall through from the previous case label is intentional.
|-
| {{cpp|[[maybe_unused]]}}
|| Suppresses compiler warnings on an unused entity.
|-
| {{cpp|[[nodiscard]]}}<br>{{cpp|[[nodiscard("reason")]]}}
|| Issues a compiler warning if the return value of the marked symbol is discarded or ignored for the reason specified (if given).
|-
| {{cpp|[[likely]]}}<br>{{cpp|[[unlikely]]}}
|| Indicates that the compiler should optimise for the case where a path of execution through a statement is more or less likely to occur than the other(s).
|-
| {{cpp|[[no_unique_address]]}}
|| Indicates that a non-static data member need not have an address distinct from all other non-static data members of its class.
|-
| {{cpp|[[assume(expression)]]}}
|| Indicates that the given expression always evaluates to {{cpp|true}} at a given point, allowing the compiler to make optimisations based on that information.
|-
| {{cpp|[[indeterminate]]}}
|| Indicates that an object bears an indeterminate value if it is not initialised.
|-
| {{cpp|[[unsequenced]]}}
|| Indicates that a function is stateless, effectless, idempotent and independent.
|-
| {{cpp|[[reproducible]]}}
|| Indicates that a function is effectless and idempotent.
|}
 
=== Scoped attributes ===
As mentioned previously, GCC and Clang have scoped (namespaced) attributes, such as {{cpp|[[gnu::always_inline]]}}, {{cpp|[[gnu::hot]]}}, and {{cpp|[[gnu::const]]}}. To apply multiple scoped attributes, one may write:
<syntaxhighlight lang="cpp">
[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]]
import myproject.Hello;
inline int f(); // declare f with four attributes
[[gnu::always_inline, gnu::const, gnu::hot, nodiscard]]
int f(); // same as above, but uses a single attr specifier that contains four attributes
// C++17:
[[using gnu : const, always_inline, hot]] [[nodiscard]]
int f[[gnu::always_inline]](); // an attribute may appear in multiple specifiers
</syntaxhighlight>
 
== Reflection ==
In addition to basic metaprogramming provided in header <code><type_traits></code>, [[C++26]] introduces compile-time reflection. Compile-time reflection capabilities can be accessed in header <code><meta></code> and declarations are stored in namespace <code>std::meta</code>.
 
=== Annotations ===
Most declarations can have annotations attached, which are just values associated with that declaration. Like [[Java annotation]]s, annotations can be accessed using reflection. Annotations are different from attributes as attributes are primarily a means to communicate information to the compiler, while annotations are a feature of reflection and allow arbitrary constants and metadata to be attached, making them customisable to programs, unlike attributes. This allows for bridging the communication between the library API and the user.
<syntaxhighlight lang="cpp">
using custom::Debug;
using custom::EnumFlag;
using custom::Rename;
 
enum class [[=EnumFlag]] Toggle: uint8_t {
Off,
On
};
 
struct [[=Debug]] Person {
[[=Rename("full name")]]
std::string fullName;
int age;
};
</syntaxhighlight>
 
The annotations have no initial meaning unless some implementations use those annotations to identify some characteristics and features.
 
Creating an annotation to generate a specialisation for <code>std::formatter<T></code> is as follows:
<syntaxhighlight lang="cpp">
template <auto V>
struct Derived {};
 
template <auto V>
inline constexpr Derived<V> Derive;
 
inline constexpr struct {} Debug;
 
template <typename T>
requires (std::meta::has_annotation(^^T, Derive<Debug>))
struct std::formatter<T> {
// ...
};
 
struct [[=Derive<Debug>]] Point {
int x;
int y;
};
 
int main() {
Point p = Point { .x = 1, .y = 2 };
hello::printHello();
// prints p = Point { .x = 1, .y = 2 }
std::println("p = {}", p);
}
</syntaxhighlight>
 
== See also ==
* [[C++ standard library]]
* [[C syntax]]
* [[Java syntax]]
* [[C Sharp syntax|C# syntax]]
* [[Rust syntax]]
 
== Notes ==
Line 564 ⟶ 717:
<ref name=cppreferencestandardlibrary>{{cite web |title=C++ Standard Library |url=https://en.cppreference.com/w/cpp/standard_library |author=cppreference.com |year=2025 |access-date=2025-02-20}}</ref>
}}
 
== See also ==
* [[C syntax]]
* [[Java syntax]]
* [[C Sharp syntax]]
 
{{C++ programming language}}