C++中declaration与define的区别

Many C++ books do not clearly state the difference between declaration and definition, or they only mention the need to support separate compilation, indicating that using the extern specifier is a declaration, while without it is a definition. In fact, I think the C++ standard describes the difference between declaration and definition more clearly.

In section 2.2.2 of “C++ Primer 5th,” it mentions the relationship between variable declarations and definitions:

To support separate compilation, the C++ language distinguishes between declarations and definitions. A declaration makes the name known to the program; a file must include the declaration of a name to use a name defined elsewhere. A definition is responsible for creating the entity associated with the name.
To declare a variable without defining it, add the extern keyword before the variable name and do not explicitly initialize the variable.

1
2
extern int i; // declares i rather than defines i
int j; // declares and defines j

Any declaration that includes an explicit initialization becomes a definition. We can give a variable marked with the extern keyword an initial value, but doing so negates the effect of extern. An extern statement containing an initializer is no longer a declaration but a definition.

1
extern double pi=3.14159; // definition

The above is the description of the relationship between variable declarations and definitions in C++ Primer. I think the description in the C++ standard is more comprehensive:

A declaration is a definition unless:

  • it declares a function without specifying the function’s body (8.4),
  • it contains the extern specifier (7.1.1) or a linkage-specification (7.5) and neither an initializer nor a function-body,
  • it declares a static data member in a class definition (9.2, 9.4),
  • it is a class name declaration (9.1),
  • it is an opaque-enum-declaration (7.2),
  • it is a template-parameter (14.1),
  • it is a parameter-declaration (8.3.5) in a function declarator that is not the declarator of a function-definition, or
  • it is a typedef declaration (7.1.3),
  • an alias-declaration (7.1.3),
  • a using-declaration (7.3.3),
  • a static_assert-declaration (Clause 7),
  • an attribute-declaration (Clause 7),
  • an empty-declaration (Clause 7), or
  • a using-directive (7.3.4).

Let me briefly translate this.
A declaration is a definition unless:

  • it declares a function but does not specify the function body.
1
int func(); // declaration
  • it contains an extern specifier or a linkage-specification (e.g., extern “C”) and has neither an initializer nor a function body.
1
2
extern int x;
extern "c" void func();
  • it declares a static data member within a class definition.
1
2
3
4
5
6
7
struct A{
A(){};
static int x; // declaration
static const int y=11; // define
// notice: non-const static data member must be initialized out of line
};
int A::x=12; // define
  • it is a class name declaration.
1
struct A;
  • it is an opaque-enum-declaration.
1
enum A:int;
  • it is a template parameter.
1
template<typename T> T f(T); // T is a declaration
  • it is a parameter declaration in a function declaration.
1
int func(int x);
  • it is a typedef declaration.
1
typedef int INT;
  • it is an alias declaration.
1
using INT=int;
  • it is a using declaration.
1
2
3
4
5
namespace A{
typedef int INT;
}

using A::INT;
  • it is a static_assert declaration.
1
static_assert(foo());
  • it is an attribute declaration.
1
[[noreturn]] void funv();
  • it is an empty declaration.
1
2
// empty-declaration:
;
  • it is a using directive.
1
using namespace std;

In the above cases, declarations are not definitions. In simple terms, a “declaration” provides name and parameter prototypes, while a “definition” provides storage allocation and the corresponding implementation.
Oh, I just realized that cppreference already has this: Define and ODR.

The article is finished. If you have any questions, please comment and communicate.

Scan the QR code on WeChat and follow me.

Title:C++中declaration与define的区别
Author:LIPENGZHA
Publish Date:2017/02/24 21:09
World Count:2.6k Words
Link:https://en.imzlp.com/posts/21831/
License: CC BY-NC-SA 4.0
Reprinting of the full article is prohibited.
Your donation will encourage me to keep creating!