Where is the standard wording allowing incomplete types in function declarations, but requiring complete types in function definitions?

梦想与她 提交于 2019-12-23 02:34:32

问题


I recently found out that the types of parameters in a non-defining function declaration may be of incomplete types. This is very exciting.

class A;
class B {
   B(A a);      // Legal! Wow!
};

The type is required to be complete only for the definition:

B::B(A a) {};   // error: ‘a’ has incomplete type

I've been trying to pin down the legalese for this, but my searches through C++11 for "[in]complete type" have yielded nothing of much interest, leading me to assume that these semantics are defined through an enigmatic maze of constructions.

Can you help me pin down the standard text that defines the above requirements for the types of function parameters being complete or otherwise, in function declarations vs definitions?

(9.2/10 and 9.4.2/2 give us the requirements for static data member declarations and non-static data member definitions in class definitions.)


回答1:


See 8.3.5p9, which lays down the exact rules. For a = delete definition, implementations are likely to accept incomplete parameter types too, retroactively (as was determined in a DR resolution by the C++ committee).

In particular, there is no action done on parameters or return values in a non-defining function declaration. Copying of arguments to parameters is done in the context of the caller. And destruction of parameters is done in the context of the callee, in the function definition. Destruction of the return value is done in the context of the caller in a function call except if the call is the topmost expression or right operand of a topmost comma operator in a decltype. Then no destruction happens because no temporary is created as a special case (to help SFINAE libraries).




回答2:


Function declaration

There doesn't appear to be anything directly addressing this. It may be that it's allowed because it is not disallowed.

7.1.1/9 tells us that it's ok for an extern declaration (which is semantically similar to a member function declaration), and shows us non-normatively that types in such declarations may be incomplete:

[C++11: 7.1.1/9]: The name of a declared but undefined class can be used in an extern declaration. Such a declaration can only be used in ways that do not require a complete class type. [ Example:

struct S;
extern S a;
extern S f();
extern void g(S);
void h() {
  g(a); // error: S is incomplete
  f(); // error: S is incomplete
}

—end example ]

Function definition (thanks litb)

[C++11: 8.3.5/9]: Types shall not be defined in return or parameter types. The type of a parameter or the return type for a function definition shall not be an incomplete class type (possibly cv-qualified) unless the function definition is nested within the member-specification for that class (including definitions in nested classes defined within the class).

Function call

[C++11: 5.2.2/4]: [..] When a function is called, the parameters that have object type shall have completely-defined object type. [ Note: this still allows a parameter to be a pointer or reference to an incomplete class type. However, it prevents a passed-by-value parameter to have an incomplete class type. —end note ] [..]



来源:https://stackoverflow.com/questions/9241255/where-is-the-standard-wording-allowing-incomplete-types-in-function-declarations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!