Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class declaration inside function parameter list

As I understand, in C++, a class declared inside function parameter list automatically goes to the enclosing scope:

void f(struct A *p) {}

void g() { A *p; f(p); }

is equivalent to:

struct A;

void f(A *p) {}

void g() { A *p; f(p); }

What section in C++ standard specifies this behavior? What about C?

Well, I guess C does not follow C++ in this case. Visual studio does not compile this code is C mode:

void g(struct A { int a; } a);

struct A a;     // 'a' uses undefined struct 'A'
like image 711
igntec Avatar asked Jun 10 '16 08:06

igntec


1 Answers

This is an elaborated-type-specifier. The relevant quote in C++14 is:

[basic.lookup.elab]/2: [...] If the elaborated-type-specifier is introduced by the class-key and this lookup does not find a previously declared type-name, or if the elaborated-type-specifier appears in a declaration with the form:

class-key attribute-specifier-seqopt identifier ;

the elaborated-type-specifier is a declaration that introduces the class-name as described in 3.3.2.

This declares the class name like so:

[basic.scope.pdecl]/7: The point of declaration of a class first declared in an elaborated-type-specifier is as follows:

— [...]

— for an elaborated-type-specifier of the form

class-key identifier

if the elaborated-type-specifier is used in the decl-specifier-seq or parameter-declaration-clause of a function defined in namespace scope, the identifier is declared as a class-name in the namespace that contains the declaration; otherwise, except as a friend declaration, the identifier is declared in the smallest namespace or block scope that contains the declaration.

So because struct A is an elaborated-type-specifier and A has not been previously declared, A is declared in the namespace that contains the declaration (in this case, the global namespace).

like image 149
TartanLlama Avatar answered Oct 12 '22 23:10

TartanLlama